Gor*_*r H 12 c# arrays large-object-heap
我有一个其他有效的问题这里关于这可能涉及LOH碎片可能还有其他未知因素中的一些绝望的内存问题.
我现在的问题是,接受的做事方式是什么?如果我的应用程序需要在Visual C#来完成,并且需要处理大型阵列的INT [4000000]调,我怎么能不被垃圾收集器拒绝处理LOH注定?
似乎我被迫将任何大型数组全局化,并且从不在它们周围使用"new"这个词.所以,我留下了带有"maxindex"变量的不合适的全局数组,而不是由函数传递的整齐大小的数组.
我总是被告知这是不好的做法.还有什么选择?
是否有某种功能System.GC.CollectLOH("Seriously")?是否有可能将垃圾收集外包给System.GC以外的其他方式?
无论如何,处理大型(> 85Kb)变量的普遍接受的规则是什么?
Pau*_*ane 26
首先,垃圾收集器确实收集了LOH,因此不要立即被它的早期吓到.收集第2代时收集LOH.
不同之处在于LOH不会被压缩,这意味着如果你的物体有一个很长的使用寿命,那么你将有效地将LOH分成两个部分 - 前面的区域和该物体之后的区域.如果这种情况继续发生,那么你可能会遇到长期对象之间的空间不足以进行后续分配的情况,并且.NET必须分配越来越多的内存以放置大对象,即LOH变得支离破碎.
现在,话虽如此,如果LOH的末端区域完全没有活物,那么LOH的大小会缩小,所以唯一的问题是如果你将物体留在那里很长时间(例如应用的持续时间).
避免LOH碎片的策略是:
编辑:双阵列的LOH阈值似乎是8k.
这是一个老问题,但我认为用.NET中引入的更改更新答案并没有什么坏处.现在可以对大对象堆进行碎片整理.显然,首选应该是确保做出最好的设计选择,但现在有这个选择是很好的.
https://msdn.microsoft.com/en-us/library/xe0c2357(v=vs.110).aspx
"从.NET Framework 4.5.1开始,您可以通过在调用Collect方法之前将GCSettings.LargeObjectHeapCompactionMode属性设置为GCLargeObjectHeapCompactionMode.CompactOnce来压缩大对象堆(LOH),如以下示例所示."
可以在System.Runtime命名空间中找到GCSettings
GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce;
GC.Collect();
Run Code Online (Sandbox Code Playgroud)
我想到的第一件事就是将阵列分成较小的阵列,这样它们就无法到达GC所需的内存来放入LOH.你可以将数组吐成10,000个较小的数组,然后构建一个对象,根据你传递的索引器知道要查找哪个数组.
现在我还没有看到代码,但我也会质疑为什么你需要一个大的数组.我可能会考虑重构代码,因此所有这些信息不需要立即存储在内存中.
小智 6
你弄错了.你不需要有4000000的数组大小,你绝对不需要调用garbace收集器.
这允许您仅使用一个重定向访问基本上所有元素.并且,由于单个阵列较小,碎片不是问题...
......如果是......那么REUSE页面.不要把它们扔掉处理掉,把它们放在一个静态的"PageList"上并先从那里拉出来.所有这些都可以在你的课堂上透明地完成.
真正的好处是这个List在内存使用方面非常动态.您可能想要调整holder数组(重定向器)的大小.即使没有,也只是每页约512kbdata.
第二级数组基本上每字节64k - 一个类为8字节(每页512kb,32位256kb),或每个结构字节64kb.
技术上:
将int []转换为int [] []
根据需要确定32位或64位是否更好;)两者都有优点和缺点.
处理一个像这样的大型阵列在任何语言中都是不可思议的 - 如果你愿意,那么......基本上....在程序启动时分配,永远不会重新创建.只有解决方案
| 归档时间: |
|
| 查看次数: |
7329 次 |
| 最近记录: |