面试官今天问了我这个问题...有答案吗?
面试官今天问了我这个问题...有答案吗?
System.GC.Collect()
强制运行垃圾回收器。虽然这不被推荐使用,但在特定情况下可以使用。
不建议显式调用gc,但如果您调用了
GC.Collect();
GC.WaitForPendingFinalizers();
在代码中会明确调用GC,别忘记在GC.Collect()
之后调用GC.WaitForPendingFinalizers();
。
WaitForPendingFinalizers
并不一定能提供 "更好的性能":它只是简单地阻塞直到终结队列中的所有对象都被终结(这些对象可能是由你之前调用 Collect
放置在那里的)。如果你希望有机会收集这些对象,那么你需要在调用 WaitForPendingFinalizers
后再次调用 Collect
。 - LukeHWaitForPendingFinalizers
被认为很重要? - ChristianGC.Collect()
来自MDSN
使用此方法尝试回收所有不可访问的内存。
所有对象,无论它们在内存中存在多长时间,都将被考虑进行回收;但是,在托管代码中引用的对象不会被回收。使用此方法强制系统尝试回收最大量的可用内存。
不过要记住,垃圾回收器可能不会始终清理您所期望的内容...
您不希望强制垃圾回收器运行。
但是,如果您真的这样做了(当然只是作为一种纯学术练习):
GC.Collect()
我认为 .Net Framework 会自动完成这个操作,但是为了保险起见,首先确保选择要删除的内容,然后调用垃圾回收器:
randomClass object1 = new randomClass
...
...
// Give a null value to the code you want to delete
object1 = null;
// Then call the garbage collector to erase what you gave the null value
GC.Collect();
由于我的声望太低,无法评论,所以我将其发布为答案,因为它在我苦苦挣扎数小时后帮助了我,并且可能会帮助其他人:
正如大多数人所说,通常不建议使用GC.Collect()进行垃圾回收,除非是在极端情况下。作为这样一个示例,运行垃圾回收正是我场景的解决方案。
我的程序在线程中对文件执行长时间运行的操作,然后从主线程中删除该文件。但是:当文件操作引发异常时,.NET直到垃圾实际上被收集之前都不会释放文件锁,即使长时间运行的任务封装在using语句中也不会释放。因此,在尝试删除文件之前,程序必须强制执行垃圾回收。
代码如下:
var returnvalue = 0;
using (var t = Task.Run(() => TheTask(args, returnvalue)))
{
// TheTask() opens a file and then throws an exception. The exception itself is handled within the task so it does return a result (the errorcode)
returnvalue = t.Result;
}
//Even though at this point the Thread is closed the file is not released untill garbage is collected
System.GC.Collect();
DeleteLockedFile();
显式调用GC.Collect()方法可能无法清除您想要的堆内存中的对象。它在内部管理以保持应用程序可用的内存,并通过处理一段时间未使用的对象来分配对象的内存。只有在应用程序或代码在执行过程中需要更多内存时才这样做。
这里有一个替代建议。像您已经做的那样保留服务器GC。然后基于用户定义的设置,如果应用程序内存超过您确定为关键级别的某个阈值,则强制运行GC。
请注意,如果您按照此路径进行,实际上您表明您比CLR更了解垃圾收集应该何时运行。大多数情况下,我发现CLR单独工作时比我们干预它时执行得更好。
代码以检查内存使用情况并跨所有代或特定代运行GC
long UsedMemory;
//UsedMemory = GC.GetTotalMemory(false); // Not as reliable
UsedMemory = System.Diagnostics.Process.GetCurrentProcess().PagedMemorySize64;
if (UsedMemory > 1073741824) // One GB in bytes 1 X 1024 X 1024 X 1024
{
GC.Collect(); // Collect all generations
//GC.Collect(2,GCCollectionMode.Forced);; Or collect a specific generation and force it to run now
}