gpt4 book ai didi

c# - 垃圾收集是否在 GC.Collect() 之后立即运行?

转载 作者:太空狗 更新时间:2023-10-29 21:32:50 25 4
gpt4 key购买 nike

关闭。这个问题需要details or clarity .它目前不接受答案。












想改进这个问题?通过 editing this post 添加详细信息并澄清问题.

5年前关闭。




Improve this question




该问题仅用于研究目的。

我读过很多关于 C# 的书,这个问题总是在我脑海中浮现。我的理解是 C# 是托管代码,当 CLR 决定何时运行垃圾收集时,所有垃圾收集都会发生。开始吧。

假设我有一个简单的类 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!";
}
}

请批准或拒绝我的假设:
  • 垃圾收集不会立即在 运行,我说得对吗?第2行 ?
  • GC.Collect()只是一个请求 进行垃圾收集,它不会在第 2 行立即运行。本行 可能执行以 x 毫秒/秒为单位。
    在我看来,方法System.GC.Collect();只是对垃圾收集器说垃圾收集器应该运行垃圾收集,但是 真正的垃圾收集可能在 x 毫秒/秒内发生
  • 只有垃圾收集器知道何时运行垃圾收集。如果第 0 代有空闲空间,那么 中不会发生垃圾回收。第 2 行: row2: System.GC.Collect();
  • 由于我们在托管环境中进行编程,因此不可能立即运行垃圾收集,只有 CLR 决定何时运行垃圾收集。 垃圾收集可以在 x 毫秒/秒内运行或垃圾收集 可能无法运行 导致在调用方法 GC.Collect() 后第 0 代有足够的空间来创建新对象.程序员可以做的就是让CLR通过方法GC.Collect()运行垃圾回收。 .

  • 更新:

    我已阅读 this msdn article about GC.Collect Method () . .但是,我不清楚何时开始真正清除未引用的对象。 MSDN 说:

    GC.Collect Method () forces an immediate garbage collection of all generations.



    然而,在 备注 我读过这个:

    Use this method to try to reclaim all memory that is inaccessible. It performs a blocking garbage collection of all generations.


  • 我对此感到困惑 “用这个方法试试”我认为垃圾收集可能不会发生原因 CLR 确定有足够的空间来创建新对象。我对吗?
  • 最佳答案

    简短回答

    调用GC.Collect()将执行完整的垃圾回收并等待它完成,但它不会等待任何挂起的终结器运行。

    长答案

    您的假设部分正确,因为用于运行终结器的 GC 在一个或多个后台线程中运行。 (但请参阅此答案末尾的脚注。)

    但是,可以通过调用 GC.WaitForFullGCComplete() 等待完整的 GC 完成。和 GC.WaitForPendingFinalizers() 在您调用 GC.Collect() 之后:

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

    但是,请注意,运行终结器的线程未指定,因此无法保证此方法会终止。

    请注意,您通常不应该以这种方式使用 GC;我假设您有一个特殊情况需要解决,或者您这样做是出于研究目的。

    我见过的唯一有效情况是当应用程序关闭时,您想要(尝试)确保所有终结器都已运行 - 因为例如,它们将刷新日志文件等。

    如上所述,这仍然不能保证所有终结器都已运行;这是你能做的最好的。

    回答您的观点(5):

    GC.Collect() 的文档指出:

    强制所有代立即进行垃圾收集。

    所以这将强制GC。

    该文档还指出:

    使用此方法尝试回收所有不可访问的内存。

    此处使用“尝试”一词仅意味着即使运行完整的 GC,也不一定会回收所有不可访问的内存。可能发生的原因有多种,例如,终结器可能会阻塞。

    脚注

    .Net 4.5 allows you to specify whether GC.Collect() is blocking or not .

    事实上, GC.Collect() 的文档声明它执行所有代的阻塞垃圾收集,这似乎与我上面的陈述相矛盾。然而,对于这是否真的如此,似乎有些困惑。

    参见示例 this thread .

    答案是这样的: GC.Collect()默认情况下会等待所有代被 GC,但它不会等待挂起的终结器,它们总是在单独的线程中执行。

    因此,如果您不需要等待终结者,您只需调用 GC.Collect()你不需要等待其他任何事情。

    关于c# - 垃圾收集是否在 GC.Collect() 之后立即运行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34988198/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com