简体   繁体   English

如何使垃圾回收器在超出范围之前对其进行处置?

[英]How to make Garbage collector dispose a collection before it goes out of scope?

I'm aware that GC will clean objects on the heap when there's no longer any reference to them on the stack. 我知道,当堆栈上不再有任何引用时,GC会清理堆上的对象。

I wonder if there's a way to force GC to act before that. 我想知道是否有一种方法可以强制GC在此之前采取行动。 The scenario I have is something like this. 我遇到的情况是这样的。

public void A(){
    IList foo = bar();
    //does work on foo's items
    foobar();
    //more code before it goes out of scope
}

I wish I could free the memory used by the collection before calling foobar(). 我希望我可以在调用foobar()之前释放集合使用的内存。 Is there a way to do that? 有没有办法做到这一点?

ps.: I know it's bad code, but it's a legacy code which I can do nothing about right now. ps .:我知道这是不好的代码,但这是一个遗留代码,我现在什么也不能做。

UPDATE: As pointed out by InBetween , "The GC is allowed to collect any unrechable object, but it's not a certainty it will do so". 更新:正如InBetween指出的那样,“允许GC收集任何不可回收的对象,但是并不确定这样做。” Unfortunately, I have a memory requirement from some users and the app must keep its memory usage within certain limits, otherwise I'd usually let GC do its work. 不幸的是,我对某些用户有内存要求,并且该应用程序必须将其内存使用率保持在一定范围内,否则我通常会让GC来工作。

I'm aware that GC will clean objects on the heap when there's no longer any reference to them on the stack. 我知道,当堆栈上不再有任何引用时,GC会清理堆上的对象。

That is not true: 那是不对的:

var o = new object();
return new[] { o }

Ok, where exactly is the reference to o on the stack after this method returns? 确定,此方法返回后,在堆栈上对o的引用到底在哪里?

Think of it better this way: any object is eligible for collection if the GC can prove that it's not reachable any more. 可以这样考虑:如果GC可以证明它不再可访问,则任何对象都可以进行收集。 That is quite different from what you're claiming. 这与您所声称的完全不同。

Additionally, if the GC can prove that no reference to a given object is ever read from again then the object can be collected even if there is a reachable reference (because it's never used so it's as good as unreachable). 此外,如果GC可以证明没有再次读取对给定对象的引用,那么即使存在可访问的引用,也可以收集该对象(因为从未使用过该引用,因此它与不可访问一样好)。

Both these scenarios are performed by the GC for you when the GC decides it's a good time to do so; 当GC认为是时候这样做时,这两种情况都由GC为您执行。 it is much better at it than you, so let it do its job and don't worry about it. 它比您要好得多,因此让它完成工作,不要担心。 There are very little scenarios where you have to interfere with how the GC works. 在极少数情况下,您不必干预GC的工作方式。

Garbage Collection in .NET is called in 3 situations : 在以下三种情况下调用.NET中的垃圾回收:

  1. Allocation exceeds the first generation ( gen 0 ) or large object heap threshold, 分配超出了第一代(gen 0)或大对象堆阈值,
  2. System is low on memory, 系统内存不足,
  3. By calling GC.Collect method 通过调用GC.Collect方法

Judging by your "code" I can guess that it will be called as in first situation and in this case ( because you still have a reference to that object ) I would suggest you to wrap this in to some other code block. 从您的“代码”来看,我可以猜到它会像第一种情况那样被调用,在这种情况下(因为您仍然有对该对象的引用),我建议您将其包装到其他代码块中。 eg : 例如:

public void A () 
{
    DoSomethingWithTheList();
    foobar();
    //more code before it goes out of scope
}

private void DoSomethingWithTheList()
{
    IList foo = bar();
    //does work on foo's items
}

If that's not possible then just try to dereference your IList object by setting it to null and then invoke GC.Collect with the highest generation as a parameter which should do the trick. 如果不可能,则尝试通过将IList对象设置为null来取消对IList对象的引用,然后调用具有最高生成量的GC.Collect作为参数,以解决问题。

public void A ()
{
    IList foo = bar();
    //does work on foo's items
    foo = null;
    GC.Collect(2, GCCollectionMode.Forced); // force GC
    foobar();
    //more code before it goes out of scope
}

this assumes that objects in the IList foo are not referenced elsewhere 这假定IList foo中的对象未在其他地方引用

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在GC收集垃圾之前在asp.net中处理DataTable? - How to dispose DataTable in asp.net before garbage collection by the GC? 调用Dispose()vs对象超出范围/方法完成 - Calling Dispose() vs when an object goes out scope/method finishes 线程创建范围和垃圾收集器 - Thread creation scope and the garbage collector 关闭范围和垃圾回收 - Closure scope and garbage collection 我需要在我的 Dispose() 方法中调用垃圾收集器吗 - Do i need to call garbage collector inside my Dispose() method 当我捕获了子属性时,父对象超出了范围-它何时处理子属性? - Parent object goes out of scope when I have captured child property - when does it dispose the child property? 如何强制垃圾收集器运行? - How to force garbage collector to run? 如何在失去作用域之前修复CA Dispose对象? - How to fix CA Dispose objects before losing scope? 如果我引用了超出范围的对象的对象属性,则可以对外部对象进行垃圾回收吗? - If I reference an object property of an object that goes out of scope is the outer object eligible to be garbage collected? 析构函数方法是否由垃圾收集器隐式使用,并且配置开发人员用于显式处理对象的方法? - Are destructor methods used implicitly by the garbage collector, and dispose methods used by developers to explicitly dispose of objects?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM