强制对数组进行垃圾回收,C# [英] Force garbage collection of arrays, C#

查看:62
本文介绍了强制对数组进行垃圾回收,C#的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个问题,几个 3 维数组分配了大量内存,程序有时需要用更大/更小的数组替换它们并抛出 OutOfMemoryException.

I have a problem where a couple 3 dimensional arrays allocate a huge amount of memory and the program sometimes needs to replace them with bigger/smaller ones and throws an OutOfMemoryException.

示例:分配了 5 个 96MB 数组(200x200x200,每个条目 12 字节数据),程序需要将它们替换为 210x210x210(111MB).它以类似于此的方式执行此操作:

Example: there are 5 allocated 96MB arrays (200x200x200, 12 bytes of data in each entry) and the program needs to replace them with 210x210x210 (111MB). It does it in a manner similar to this:

array1 = new Vector3[210,210,210];

其中 array1-array5 是之前使用的相同字段.这应该将旧数组设置为垃圾收集的候选者,但似乎 GC 的动作不够快,并在分配新数组之前留下分配的旧数组 - 这会导致 OOM - 而如果它们在新分配之前被释放,则空间应该是够了.

Where array1-array5 are the same fields used previously. This should set the old arrays as candidates for garbage collection but seemingly the GC does not act quickly enough and leaves the old arrays allocated before allocating the new ones - which causes the OOM - whereas if they where freed before the new allocations the space should be enough.

我正在寻找一种方法来做这样的事情:

What I'm looking for is a way to do something like this:

GC.Collect(array1) // this would set the reference to null and free the memory
array1 = new Vector3[210,210,210];

我不确定完整的垃圾收集是否是一个好主意,因为该代码可能(在某些情况下)需要相当频繁地执行.

I'm not sure if a full garbage collecion would be a good idea since that code may (in some situations) need to be executed fairly often.

有正确的方法吗?

推荐答案

这不是原始问题如何强制 GC"的准确答案,但是,我认为它会帮助您重新审视您的问题.

This is not an exact answer to the original question, "how to force GC', yet, I think it will help you to reexamine your issue.

>

看到你的评论后,

After seeing your comment,

  • 放置 GC.Collect();似乎有帮助,尽管它仍然不能完全解决问题 - 由于某种原因,当分配了大约 1.3GB 时程序仍然崩溃(我正在使用 System.GC.GetTotalMemory(false); 来查找分配的实际数量).

我怀疑您可能有内存碎片.如果对象很大(我没记错的话.net 2.0 CLR下85000字节,不知道有没有改过),对象会被分配到一个特殊的堆中,Large Object Heap (LOH).GC 确实回收了 LOH 中无法访问的对象正在使用的内存,但是,由于性能原因,它不会像 LOH 中的其他堆(gen0、gen1 和 gen2)那样执行压缩.

I will suspect you may have memory fragmentation. If the object is large (85000 bytes under .net 2.0 CLR if I remember correctly, I do not know whether it has been changed or not), the object will be allocated in a special heap, Large Object Heap (LOH). GC does reclaim the memory being used by unreachable objects in LOH, yet, it does not perform compaction, in LOH as it does to other heaps (gen0, gen1, and gen2), due to performance.

如果你经常分配和释放大对象,它会使 LOH 碎片化,即使你有比你需要的更多的可用内存,你可能不再有连续的内存空间,因此,会得到 OutOfMemory 异常.

If you do frequently allocate and deallocate large objects, it will make LOH fragmented and even though you have more free memory in total than what you need, you may not have a contiguous memory space anymore, hence, will get OutOfMemory exception.

目前我可以想到两种解决方法.

I can think two workarounds at this moment.

  1. 转向 64 位机器/操作系统并利用它:)(最简单,但也可能最难,具体取决于您的资源限制)
  2. 如果你做不到#1,那么首先尝试分配一大块内存并使用它们(可能需要编写一些辅助类来操作较小的数组,实际上它驻留在较大的数组中)以避免碎片.这可能会有所帮助,但是,它可能无法完全解决问题,您可能必须处理复杂性.

这篇关于强制对数组进行垃圾回收,C#的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆