C# 垃圾收集是否在GC.Collect()之后立即运行?
这个问题只是为了研究目的 我读过很多关于C#的书,我总是想到这个问题。据我所知,C#是托管代码,所有垃圾收集都发生在CLR决定何时运行垃圾收集时。让我们开始吧 让我们假设我有一个简单的类C# 垃圾收集是否在GC.Collect()之后立即运行?,c#,.net,garbage-collection,garbage,C#,.net,Garbage Collection,Garbage,这个问题只是为了研究目的 我读过很多关于C#的书,我总是想到这个问题。据我所知,C#是托管代码,所有垃圾收集都发生在CLR决定何时运行垃圾收集时。让我们开始吧 让我们假设我有一个简单的类学生: public class Student { public int IdStudent { get; set; } public string Name { get; set; } public string Surname { get; set; } } class Progra
学生:
public class Student
{
public int IdStudent { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
}
class Program
{
static void Main(string[] args)
{
This is row1: Person person = new Person() {IdPerson=1, Name="Bill", SurName="Collins"};
This is row2: System.GC.Collect();
This is row3: string str="Hello World!";
}
}
请批准或拒绝我的假设:
在第2行中没有立即运行垃圾收集,这对吗
GC.Collect()
只是一个请求,用于进行垃圾收集,该垃圾收集不会立即在第2行运行。此行可能在x毫秒/秒内执行。
在我看来,方法System.GC.Collect()代码>只是告诉垃圾收集器垃圾收集器应该运行垃圾收集,但是真正的垃圾收集可能会在x毫秒/秒内发生
只有垃圾收集器知道何时运行垃圾收集。如果第0代中有可用空间,则不会在行2:行2:System.GC.Collect()中进行垃圾回收代码>
不可能立即运行垃圾收集,因为我们正在托管环境中编程,只有CLR决定何时运行垃圾收集。垃圾收集可以在x毫秒/秒内运行,或者垃圾收集可能不运行因为第0代中有足够的空间创建新的垃圾收集调用方法GC.Collect()
后的对象。程序员可以做的只是让CLR通过方法GC.Collect()
运行垃圾收集
更新:
我读过。然而,我不清楚何时开始真正清除未引用的对象。MSDN说:
Collect方法()强制立即对所有
几代人
然而,在评论中,我读到了这一条:
使用此方法尝试回收所有不可访问的内存。信息技术
执行所有代的阻塞垃圾收集
我对这个“使用此方法尝试”感到困惑,我认为垃圾收集可能不会发生因为CLR决定有足够的空间来创建新对象。我说得对吗
简短回答
调用GC.Collect()
将执行完整的垃圾收集并等待它完成,但不会等待任何挂起的终结器运行
长答案
您的假设部分正确,因为运行终结器的GC在一个或多个后台线程中运行。(但请参见本答案末尾的脚注。)
但是,可以通过调用和调用GC.Collect()
,等待完成GC:
但是,请注意,运行终结器的线程是未指定的,因此不能保证此方法将终止
注意,您通常不应该以这种方式使用GC;我假设你有一个特殊的情况,你需要解决,或者你这样做是为了研究目的
我见过的唯一有效的情况是当应用程序关闭时,您希望(尝试)确保所有终结器都已运行,因为,例如,它们将刷新日志文件等
如上所述,这仍然不能保证所有终结器都已运行;这是你能做的最好的了
关于你的第(5)点:
GC.Collect()的文档说明:
强制立即对所有代进行垃圾收集
所以这将强制GC
文件还指出:
使用此方法尝试回收所有不可访问的内存
在那里使用“try”一词仅仅意味着即使运行完整的GC,也不一定会回收所有不可访问的内存。可能会出现以下几种原因,例如,终结器可能会阻塞
脚注
.Net 4.5
事实上,GC.Collect()
的文档说明它执行所有代的阻塞垃圾收集,这似乎与我上面的陈述相矛盾。然而,对于是否真的是这样,似乎存在一些困惑
例如,见
答案是:GC.Collect()
默认情况下将等待所有代被GCed,但它不会等待挂起的终结器,这些终结器总是在单独的线程中执行
因此,如果您不需要等待终结器,您只需要调用GC.Collect()
,而不需要等待任何其他操作。有两个GC,我相信您希望从您的代码中了解工作站GC。哪种方法通过在完整收集期间并发运行来最小化暂停?工作站GC使用第二个处理器并发运行收集,在减少吞吐量的同时最小化延迟。如果服务器GC没有正常工作,我们应该只担心GC的行为。如果您按照工作站GC在代码中添加GC.collect(),则这在服务器GC上可能是无用的
服务器GC是为实现最大吞吐量而设计的,并且具有非常高的性能。服务器上的内存碎片是一个比工作站上严重得多的问题,这使得垃圾收集成为一个有吸引力的提议。在单处理器场景中,两个采集器的工作方式相同:工作站模式,没有并发采集
我对使用这种方法进行尝试感到困惑,我认为垃圾收集可能不会发生,因为CLR决定有足够的空间来创建新对象。我说得对吗
对于workstaion GC,GC.Collect将尽快开始收集,您可以假设它会立即安全收集。哦,它肯定会运行,但您是否询问它是否收集特定的内容
GC.Collect();
GC.WaitForPendingFinalizers();
GC.WaitForFullGCComplete();