我使用的是 .NET 4.0,因此有 2 GB 的限制
此 get 大约有 1/2 的时间抛出内存不足异常
public IEnumerable<FTSword7bitThesaurus> FTSwordsPlusSelected
{
get
{
try
{
return FTSWords7bit.Select(w => new FTSword7bitThesaurus(this, w, selectedKeys.Contains(w.Key)));
}
堆栈跟踪开始:
System.Collections.Generic.List'1_setCapacity(int32值)
这是调用 get 的代码
<ListView Grid.Row="4" Grid.Column="1" x:Name="lvFTSWordsMine"
ItemsSource="{Binding ElementName=lvThesarus, Path=SelectedItem.FTSwordsPlusSelected, Mode=OneWay}"
ScrollViewer.VerticalScrollBarVisibility="Visible" ScrollViewer.HorizontalScrollBarVisibility="Hidden" VerticalContentAlignment="Stretch">
但令我困惑的是 FTSwordsPlusSelected (应该)小于 FTSWords7bit
这是FTSword7bitThesaurus中唯一的数据
一个 bool 值和两个引用
public class FTSword7bitThesaurus : INotifyPropertyChanged
{
bool selected = false;
FTSword7bit fTSword;
FTSthersarus fTSthersarus;
FTSWord7bit 平均有 20 个字节的数据
FTSWords7bit 集合大小为 1200 万 FTSWord7bit
该集合(尚未)抛出内存不足异常
我在收集我认为应该较小的对象时内存不足
我无法分析整个集合,因为分析器犹豫不决
selectedKeys 只是一个 HashSet,永远不会超过 10,000 个,通常少于 200
既然显然 FTSWords7bit 是首先创建的,您认为这只是由于内存碎片吗?
关于如何避免内存不足问题有什么想法吗?
FTSWords7bit 被广泛使用,我一直坚持使用
FTSword7bitThesaurus 仅由一个管理屏幕使用,我希望当他们退出该屏幕时将其丢弃
大多数时候收集的数据少于 100 万,但这是一个奇怪的数据集
如果我能稳住1200万就OK
我们甚至可以忍受 1/2 时间内存不足的情况,但这并不能增强用户的信心
距离 .NET 4.5 还需要几个月的时间
来自已接受的答案
修复方法只是分页
问题很可能是连续的内存块不可用
public void NextPage()
{
page++;
NotifyPropertyChanged("FTSwordsPlusSelected");
}
public IEnumerable<FTSword7bitThesaurus> FTSwordsPlusSelected
{
get
{
try
{
return FTSWords7bit.Skip(page * pageSize).Take(pageSize).Select(w => new FTSword7bitThesaurus(this, w, selectedKeys.Contains(w.Key)));
}
最佳答案
问题在于,您的代码不仅需要非常大的连续内存块(通过 List<>
的数组),而且还必须为 ListView
中的每个条目分配额外的内存。 。我可以想象与 ListView
相关的开销速度非常快,并且导致了问题。
有一些具有不同复杂程度的解决方案:
- 数据虚拟化 - 此解决方案最适合您的用户。本质上,该控件只会将其需要的行保留在内存中。当然,您的用户无法分辨,因此这是最好也是最复杂的解决方案。这个post有一个很好的例子。 (看起来像 Google 图片搜索)。
- 控制分页 - 该解决方案看起来更像是一个网站选项。想想普通的谷歌,他们不会向你展示无限的结果,只是一个子集。然后,他们让您选择下一页以获得更多结果。使用
IEnumerable<>
可以很好地完成此操作。因为你可以使用Skip()
和Take()
对于每页(假设每页有 25 个条目,那么您将执行Skip(25 * pageNumber).Take(25)
)。我发现这个解决方案更容易创建,但使用起来却更麻烦。
关于.net - 集合内存不足,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21121241/