-10

垃圾收集什么时候发生,在程序开始和程序结束之间?

我正在使用 C++/CLI,但这更多是关于垃圾收集的一般问题。我不确定在程序完成后是否真的会发生垃圾收集,即在程序的进程被杀死之后。或者也许所有垃圾收集都在程序结束之前完成?

谢谢

4

4 回答 4

3

只有在分配内存时才会触发垃圾回收。在第 0 代堆没有足够空间来满足请求的特定情况下。所以不,当你的程序终止时你不会得到一个,这不太可能是你分配任何东西的地方。

GC 执行了一项特殊的辅助作业,它还为任何具有终结器的对象运行终结器。终结器负责释放非内存的操作系统资源。像文件句柄、字体、设备上下文等。它们通常在对任何收集的对象进行垃圾收集之后运行,假设您没有自己处置对象。

CLR在 AppDomain 卸载并且您的程序终止之前运行这些终结器。

于 2013-07-18T15:12:34.690 回答
2

C++ 不实现任何类型的垃圾回收。

如果您的应用程序使用 RAII 对象,则应通过堆栈展开来收集它们的资源,只要其中一个超出范围(即在范围末端调用析构函数时)或抛出异常。

您可以独立于 RAII 实现来实现自己的垃圾收集(例如,如果您有一个高吞吐量线程,不能浪费时间等待删除调用,您可以将指针传递给负责删除它们的单独线程)。在这种情况下,答案是“取决于你如何实现它”。

在以支持垃圾收集的语言实现的应用程序中,这取决于实现。

于 2013-07-18T14:47:57.377 回答
1

简短的回答:你不知道,也不应该知道。就您而言,这无关紧要,除非您处于内存极度受限的环境中,但在这些情况下,您为什么首先使用托管代码?

就您的问题而言,当您进行研究时,所有 .NET 语言都共享一个运行时,因此它们具有相同的垃圾收集器。.NET 只看到 IL 代码;它不在乎你是用 C# 还是 C++/CLI 编写的。因此,您可能应该搜索“.NET 垃圾收集器何时运行”,这(第一次在谷歌上点击)导致了这个 SO question。阅读几个答案,你应该得到你需要知道的东西。

于 2013-07-18T14:56:45.090 回答
0

基本上 GC 在开始时运行以基于您声明为静态或全局的所有 CLI/.Net 对象构建其托管内存表示(不确定 CLI 是否可能)

在执行 GC 跟踪托管引用期间,如果您的代码不再引用 1,他应该清理它

  system::string^ st = gcnew system::string; //(1)
  st = gcnew system::string ; (2)

在这里,(2)覆盖由(1)创建的引用,GC应该获取您在(1)处创建的引用(内存)并将其放入要释放的内存列表中!因为我想在运行可能消耗 CPU 和时隙的东西之前,它等待有一种更大的内存集来清理!

它在最后运行以清除您使用“gcnew”分配的所有对象。而且都是静态的和全局的。

于 2013-07-18T15:09:34.393 回答