如何尽快释放被占用的大对象内存?
How to release the memory which is occupied but large object as soon as possible?
我有这样的方法
public void MainMethod()
{
while(true)
{
var largeObject = GetLargeObject();
............
//some work with this largeObject
............
//how to release the memory from largeObject here
}
}
显然,我将在循环中使用 break
。
在这段代码的使用中,我的记忆很快就会被垃圾填满。
有没有办法通过 GC.Collect()
释放使用某些对象(例如 largeObject)而没有 运行 垃圾收集器的内存?不只是将这个对象标记为可以被 GC 收集的对象,而是释放内存?或者 GC 在迭代结束后立即收集 largeObject
,因为它不再被使用了?
只要理解了IDisposable
的实现和调用Dispose()
只是标记对象为GC而不是立即释放内存(所以GC运行时会释放内存)
P.S。别跟我说“GC会为你收集一切”,我知道
首先。大对象,即大于 85kb,将分配在大对象堆 (LOH) 上。大型对象堆仅在第 2 代集合中收集,即集合很昂贵。因此,通常建议避免频繁的 LOH 分配。如果可能的话,重用同一个对象,或者使用内存池来避免频繁分配。
如果不让 GC 执行其操作,则无法显式释放托管内存。虽然标准建议是单独使用 GC,但在某些情况下手动 运行 可能更有意义。就像你最近释放了大量内存,并且在那个时间点收集的性能影响是可以接受的。
如果对象足够小以适合小型对象堆,那么您无需担心。第 1 代集合相当便宜,虽然如果您进行多次分配,集合将需要 运行 更频繁,但 运行 集合的时间与释放的内存量不成比例。也就是说,重用内存可能仍然是一个好主意。
最后,如果您怀疑它有问题,请进行一些分析。一些分析器会告诉您垃圾收集所花费的时间,以及分配率。在确认它确实是一个问题之前,不要尝试修复一个想象中的问题,并且您可以验证该修复实际上是一种改进。
我有这样的方法
public void MainMethod()
{
while(true)
{
var largeObject = GetLargeObject();
............
//some work with this largeObject
............
//how to release the memory from largeObject here
}
}
显然,我将在循环中使用 break
。
在这段代码的使用中,我的记忆很快就会被垃圾填满。
有没有办法通过 GC.Collect()
释放使用某些对象(例如 largeObject)而没有 运行 垃圾收集器的内存?不只是将这个对象标记为可以被 GC 收集的对象,而是释放内存?或者 GC 在迭代结束后立即收集 largeObject
,因为它不再被使用了?
只要理解了IDisposable
的实现和调用Dispose()
只是标记对象为GC而不是立即释放内存(所以GC运行时会释放内存)
P.S。别跟我说“GC会为你收集一切”,我知道
首先。大对象,即大于 85kb,将分配在大对象堆 (LOH) 上。大型对象堆仅在第 2 代集合中收集,即集合很昂贵。因此,通常建议避免频繁的 LOH 分配。如果可能的话,重用同一个对象,或者使用内存池来避免频繁分配。
如果不让 GC 执行其操作,则无法显式释放托管内存。虽然标准建议是单独使用 GC,但在某些情况下手动 运行 可能更有意义。就像你最近释放了大量内存,并且在那个时间点收集的性能影响是可以接受的。
如果对象足够小以适合小型对象堆,那么您无需担心。第 1 代集合相当便宜,虽然如果您进行多次分配,集合将需要 运行 更频繁,但 运行 集合的时间与释放的内存量不成比例。也就是说,重用内存可能仍然是一个好主意。
最后,如果您怀疑它有问题,请进行一些分析。一些分析器会告诉您垃圾收集所花费的时间,以及分配率。在确认它确实是一个问题之前,不要尝试修复一个想象中的问题,并且您可以验证该修复实际上是一种改进。