ChatGPT解决这个技术问题 Extra ChatGPT

如何强制垃圾收集器运行?

c#

面试官今天问我这个...有答案吗?

这个问题有很好的信息说明为什么你不应该这样做:stackoverflow.com/questions/118633/…
你为什么这样说
@Jason - 也许面试官不想听到解决方案,而是想了解 Andrew 的知识和反对这样做的理由,那么这个问题就很有意义了。
@martinstoeckli 这仍然是一个可怕的问题。在压力很大的面试中掌握知识的人不会意识到这是一个技巧问题,或者想提供额外的信息。那么这个问题并不能帮助面试官区分有知识的人还是没有知识的人。所以这个问题还是很可怕的。
“什么时候强制垃圾回收?”对我来说听起来像是一个很好的面试问题(“如何”:不是那么多)。初学者:我不知道。中级:从不。专家:当你写一个内存泄漏测试时。

P
Pang

System.GC.Collect() 强制垃圾收集器运行。不建议这样做,但可以在出现情况时使用。


为什么不推荐?
GC.Collect() 运行起来很昂贵。做超过必要的事情是不可取的。什么时候应该调用它的代码写得很好。您通常应该只在专门的边缘情况下自行收集。 stackoverflow.com/a/21961777/2710988
C
CMedina

不建议显式调用 gc,但如果调用

GC.Collect();
GC.WaitForPendingFinalizers();

它将在您的代码中显式调用 GC,不要忘记在 GC.Collect() 之后调用 GC.WaitForPendingFinalizers();


WaitForPendingFinalizers 不一定提供“更好的性能”:它只是阻塞,直到完成队列中的所有对象都已完成(您之前调用 Collect 时可能已将这些对象放在那里)。如果您希望有机会收集这些对象,则需要 另一个 调用 Collect 调用 WaitForPendingFinalizers
由于调用 gc.Collect 的少数几个好理由之一是作为释放未正确处理的资源的最后努力,WaitForPendingFinalizers 似乎是必要的步骤。不过,不确定在这种情况下避免过度调用 gc.Collect 的最佳做法是什么。顺便说一句,我想知道 gc.Collect “必须”促进几代人是否有任何技术原因?让几代人留在原地似乎更有用,除非已经分配了足够的东西来证明推进它的合理性。
C# 初学者注意事项(像我一样):GC 强制调用不能保证,一些具体未使用的对象会从内存中删除。 (一种方法是使用“使用语句”(msdn.microsoft.com/ru-ru/library/yh598w02(v=vs.80).aspx))
为什么调用 WaitForPendingFinalizers 很重要?
S
Srinivas Reddy Thatiparthy
GC.Collect() 

MDSN

使用此方法尝试回收所有不可访问的内存。所有对象,无论它们在内存中存在多长时间,都会被考虑收集;但是,不会收集托管代码中引用的对象。使用此方法强制系统尝试回收最大数量的可用内存。


m
J
Justin Niessner

GC.Collect();

但请记住,垃圾收集器可能并不总是清理您所期望的......


你是什么意思?它可以意外清洁什么?
@Voldemort - 它不会意外地清理任何东西。但它可能无法清理您期望的所有内容。
t
thecoop

您不想强制垃圾收集器运行。

但是,如果你曾经做过(当然,作为纯粹的学术练习):

GC.Collect()

我更喜欢@Karthik 的回答,在某些情况下应用程序应该合法地调用 GC.Collect()。不过很少见。
假设您有一组弱引用,并想检查是否存在任何“实时”引用。在检查之前调用 GC.Collect() 是有意义的。只是说。
投反对票,因为开场白实际上不正确;是的,我确实想强制垃圾收集器运行。
y
yagohaw

我认为 .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();

我想就是这样..希望我能帮助别人。


D
David

由于我的声誉太低而无法发表评论,因此我将其发布为答案,因为它在经过数小时的挣扎后拯救了我,并且可能对其他人有所帮助:

正如大多数人所说 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();

W
Waruna Manjula

这是一个替代建议。保持服务器 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
}