li>如上所述,这仍然不能保证所有终结器都已运行;这是您所能做的最好的事情.针对您的观点(5): GC.Collect()的文档指出: 强制立即进行所有世代的垃圾回收. 因此,此将强制执行GC.文档还指出: 使用此方法尝试回收所有不可访问的内存. 在此使用"try"一词仅意味着即使运行了完整的GC,也不一定会收回所有无法访问的内存.可能有多种原因发生,例如,终结器可能会阻塞. 脚注 .Net 4.5 可让您指定 GC.Collect()是否被阻止.实际上, GC.Collect()的文档指出它执行了所有世代的阻塞垃圾收集,这似乎与我上面的陈述相矛盾.但是,对于是否确实如此,似乎有些困惑.例如参见此线程.答案是这样的: GC.Collect()默认情况下将 等待所有世代的GC,但它不会等待待决的终结器(通常是终结器)在单独的线程中执行.因此,如果您不需要等待终结器,则只需调用 GC.Collect()即可,而无需等待其他任何东西.The question is just for research purposes.I've read many books about C# and this question always comes to my mind. What I understood that C# is managed code and all garbage collection occurs when CLR decides when to run garbage collection. Let's start.Let's imagine that I have simple class Student: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!"; }}Please, approve or reject my suppositions:Am I right that garbage collection is not run immediately at row2?GC.Collect() is just a request to make a garbage collection which DOES NOT RUN IMMEDIATELY at row2. This row maybe executed in x milliseconds/seconds.In my view, method System.GC.Collect(); just says to garbage collector that garbage collector should run garbage collection, but real garbage collection may occur in x milliseconds/secondsOnly garbage collector knows when garbage collection will be run. And If there is free space in Generation 0, then garbage collection will not occur in the row2: row2: System.GC.Collect();It is not possible to run garbage collection immediately as we are programming in managed environment and only CLR decides when to run garbage collection. Garbage collection can be run in x milliseconds/seconds or garbage collection maybe not run cause there is enough space in generation 0 to create new objects after calling method GC.Collect(). What programmer can do is just ask CLR to run garbage collection by method GC.Collect().Update:I've read this msdn article about GC.Collect Method ().. However, it is unclear to me when real clearing of unreferenced objets is started. MSDN says: GC.Collect Method () forces an immediate garbage collection of all generations.However, in Remarks I've read this one: Use this method to try to reclaim all memory that is inaccessible. It performs a blocking garbage collection of all generations.I am confused by this "Use this method to TRY" and I think that garbage collection may not occur cause CLR decides that there is enough space to create new objects. Am I right? 解决方案 SHORT ANSWERCalling GC.Collect() will do a complete garbage collection and wait for it to finish, but it will NOT wait for any pending finalizers to run.LONG ANSWERYou're partially right in your suppositions because the GC for running finalizers runs in one or more background threads. (But see the footnote at the end of this answer.)However, it is possible to wait for a complete GC to finish by calling GC.WaitForFullGCComplete() and GC.WaitForPendingFinalizers() after you have called GC.Collect():GC.Collect();GC.WaitForPendingFinalizers();GC.WaitForFullGCComplete();However, be aware that The thread on which finalizers are run is unspecified, so there is no guarantee that this method will terminate.Note that you should not normally use the GC in this way; I assume you have a special case that you need to address, or you are doing this for research purposes.The only valid case I've seen for this is when an application is closing, and you want to (try to) ensure that all finalizers have been run - because, for example, they will flush log files etc.As noted above, this still doesn't guarantee that all finalizers have been run; it's just the best you can do.In answer to your point (5):The documentation for GC.Collect() states:Forces an immediate garbage collection of all generations.So this will force a GC.The documentation also states:Use this method to try to reclaim all memory that is inaccessible.The use of the word "try" there merely means that even if a full GC is run, not all inaccessible memory will necessarily be reclaimed. There are several reasons that can occur, for example, a finalizer may block.Footnote.Net 4.5 allows you to specify whether GC.Collect() is blocking or not.In fact, the documentation for GC.Collect() states that It performs a blocking garbage collection of all generations, which would appear to contradict my statements above. However, there seems to be some confusion as to whether this really is the case.See for example this thread.The answer is this: GC.Collect() will by default wait for all generations to be GCed, but it will NOT wait for pending finalizers, which are always executed in a separate thread.Hence if you do not need to wait for finalizers, you ONLY need to call GC.Collect() and you do NOT need to wait for anything else. 这篇关于GC.Collect()之后是否立即运行垃圾回收?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!
09-02 23:41