c# 析构函数(和终结器?)在程序结束时自动调用 - 我应该对此做些什么吗?

标签 c# garbage-collection finalizer

所以我一直在阅读大量关于如何处理内存分配和终结器等的帖子...我想我对此很清楚,直到我看到从运行程序中获得的调试。该程序本身位于安全网络上,并且我的“互联网访问”PC 没有 C#,因此下面未经测试的示例可能不会给出完全相同的行为,但希望能够展示我所看到的内容:

我有两个文件:

cli.cs

for (int i = 1; i <= 3; i++)
{
    Console.WriteLine("------ ITERATION " + i + "------");
    Regression.Tests.FileOperations.runTest();
}
Console.WriteLine("Test Finished");

FileOperations.cs

class FileOperations
{
    Obj1 obj1 = null;
    Obj2 obj2 = null;

    public void doStuff()
    {
        // Clear the objects
        obj1 = null;
        obj2 = null;

        // Create the objects
        obj1 = new Obj1();
        obj2 = new Obj2();

        // do stuff (in this case just sleep for 5 seconds)
        Thread.Sleep(5000);
    }

    // Static function so its can be called without instance
    static public void runTest()
    {
        FileOperations fileOps = new FileOperations();
        fileOps.doStuff();
    }
}
  • 因此,在 cli.cs 中,我们在循环中调用静态函数 runTest() 迭代3次。
  • runTest() 实例化一个 FileOperations 对象并 然后调用它的 doStuff() 函数。
  • doStuff() 通过将以前的对象设置为 null 来清除它们(我读到这是这样做的方法)。然后它创建对象的新实例以供使用。

所以我对此进行了测试,一切似乎都正常。然而,我的程序的输出给了我这个调试:

------ ITERATION 1 ------
------ ITERATION 2 ------
------ ITERATION 3 ------
Test Finished
~Obj1()
~Obj2()
~Obj1()
~Obj2()
~Obj1()
~Obj2()

那么,如果我正确地清除了对象(我可能没有正确清除?),为什么我的所有 Obj1 和 Obj2 仅在程序结束时才被删除? - 也许这是正确的? - 我还没有找到任何具有相同输出的人的例子......

最佳答案

您只有 3 次迭代,因此您的程序中没有多少时间点可以进行 Garabage-Collection。因此,即使 GC 会启动三次(在这个小场景中我对此表示怀疑),您也无法确定这是发生在下一次迭代之前还是之后 全部。 GarbageCollection 的过程非常复杂,尤其是不确定性,因此您无法确定实例何时从内存中释放。

尽管您有三个不同的 FileOperations 实例,它们分别拥有自己的 Obj1Obj2 实例,但这些实例可能会也可能不会保留在堆,直到 GC 最终决定启动。这种情况至少在您的应用程序终止时发生,但通常要早得多。您对 GC 唯一可以期望的是它将会运行。 GC 在另一端工作的点是当实例超出范围并且不再存在对该实例的引用时。在您的情况下,这是当您的代码中不再使用 FileOperations 的实例时。

因此,在您的场景中或多或少有两个选择:

  1. GC 在每次迭代或至少其中一些迭代中工作,至少早于您的应用终止
  2. 当您的应用终止时

由于您的程序太少,发生第二种选择的可能性非常高。顺便说一句,这提高了整体性能,因为 GC 不需要一直工作 - 或者特别是释放任何实例 - 只需几次(或者在您的情况下可能是一次)。

关于c# 析构函数(和终结器?)在程序结束时自动调用 - 我应该对此做些什么吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46420901/

相关文章:

c# - itextsharp 在表格单元格中的圆形图像上添加文本

garbage-collection - D垃圾收集器有用吗?

c# - 为什么 WeakReference.IsAlive 变为假?

C# 自动生成的方法。如何添加附加参数

c# - Task.Factory.StartNew() Taskscheduler 参数

c# - 如何以特定格式显示日期?

memory-management - 垃圾收集器收集堆栈内存、堆内存还是两者兼而有之?

debugging - 由于 "code is optimized"异常,无法使用 Mdbg 进行 func-eval

java - Java 中是否保证调用终结器?

.net - 从终结器调用RCW是否安全?