【问题标题】:How to release the memory which is occupied but large object as soon as possible?如何尽快释放被占用但对象较大的内存?
【发布时间】:2021-05-31 22:52:08
【问题描述】:

我有这样的方法

 public void MainMethod()
    {
        while(true)
        {
             var largeObject = GetLargeObject();
             ............
             //some work with this largeObject
             ............
             //how to release the memory from largeObject here
        }
    }

显然,我会在循环中使用break

在这段代码的使用中,我的记忆很快就会充满垃圾。 有没有办法释放使用某些对象(例如,大对象)的内存,而无需通过GC.Collect() 运行垃圾收集器?不只是将此对象标记为可以被 GC 收集的对象,而是释放内存?或者 GC 会在迭代结束后立即收集 largeObject,导致它不再使用?

只要我理解IDisposable的实现并调用Dispose()只是标记对象进行GC而不是立即释放内存(所以当GC运行时内存会被释放)

附:不要说我“GC会为你收集一切”,我知道

【问题讨论】:

  • 我猜您第一次询问时没有得到满意的答复。您是否考虑过分析代码以查看会发生什么? Visual Studio 的诊断工具可能会有所帮助。 GC 不调用 Dispose(),它调用终结器,因此实现 IDisposable 对您没有任何魔力,您必须实现逻辑并调用 Dispose 来清理资源,但您仍然必须等待 GC 收集。
  • 使用large object pool 之类的东西可能会更好。

标签: c# .net memory-management garbage-collection clr


【解决方案1】:

首先。大对象,即大于 85kb 的对象,将被分配在大对象堆 (LOH) 上。大对象堆只收集在第 2 代集合中,即集合很昂贵。因此,通常建议避免频繁的 LOH 分配。如果可能,重用同一个对象,或者使用内存池来避免频繁分配。

如果不让 GC 做自己的事情,就无法显式释放托管内存。虽然标准建议是不理会 GC,但在某些情况下手动运行它可能是有意义的。例如,如果您最近释放了大量内存,并且此时集合对性能的影响是可以接受的。

如果对象足够小以适合小对象堆,那么您不必担心它。第 1 代集合相当便宜,如果执行多次分配,集合需要更频繁地运行,但运行集合的时间与释放的内存量不成正比。也就是说,重用内存可能仍然是一个好主意。

最后,如果您怀疑这是一个问题,请进行一些分析。一些分析器为您提供垃圾收集所花费的时间,以及分配率。在确认它确实是一个问题之前,不要尝试修复想象中的问题,您可以验证修复实际上是一种改进。

【讨论】:

    猜你喜欢
    • 2013-10-05
    • 1970-01-01
    • 2012-01-25
    • 2015-10-26
    • 2013-02-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-27
    相关资源
    最近更新 更多