【问题标题】:Garbage collector for managed c++托管 C++ 的垃圾收集器
【发布时间】:2014-10-30 18:55:56
【问题描述】:

通常在带有指针的 C++ 中,如果要创建一个动态对象以作为参数传递给函数,它会这样做

Object *myObj = new Object;
someFunction(myObj);
delete myObj;
myObj = nullptr;

相对

someFunction(new Object);

为了不泄漏内存。现在假设我正在创建一个垃圾收集对象;相同的规则是否仍然适用,或者垃圾收集器实际上能够从函数调用中创建的内存中删除动态创建的对象,如下所示?

someFunction(gcnew Object);

【问题讨论】:

  • 分配是否在 () 之间无关紧要。
  • 您不再需要跟踪您使用托管 C++ 创建的所有对象。即使您的对象在 () 中创建,您的 C++/CLI 对象也会按预期被垃圾收集器收集和销毁。

标签: memory-management garbage-collection c++-cli managed-c++


【解决方案1】:
    someFunction(gcnew Object);

当然,没关系。该对象不会长期存在,如果 someFunction 不以其他方式存储引用,则下一代 #0 集合可能会破坏它。你可以声明一个变量,但这没有意义,它会在运行时被抖动优化器删除,你最终会得到完全相同的代码。


请记住,delete 运算符仍然存在于 C++/CLI 中。但是与在原生 C++ 中所做的事情完全不同。它调用一个类的 IDisposable::Dispose() 实现方法。这提供了“确定性破坏”,就像在 C++ 中一样。不完全正确的词,它确实是确定性清理。该接口由存储“昂贵”操作系统资源的任何托管类实现,您不希望在垃圾收集器清理它之前一直闲逛。

样板示例是 System::Drawing::Bitmap 类。一个非常小的类,它是一大块地址空间和(可能)被锁定的文件的包装器。您要确保在不再需要它时将其丢弃。你可以这样写代码:

void dosomething() {
    Bitmap^ bmp = gcnew Bitmap("foo.png");
    drawBitmap(bmp);
    delete bmp;
}

但这不是正确的代码,它不是异常安全的。当 drawBitmap 抛出异常时,将绕过 delete 运算符调用。顺便说一句,这不是世界末日,这实际上不会导致泄漏,因为 GC 最终清理它。尽管如此,还是不​​愉快,所以 C++/CLI 设计者想出了一个模拟原生 C++ RAII 模式,在 C++/CLI 中称为“堆栈语义”:

void dosomething() {
    Bitmap bmp("foo.png");    // NOTE: no ^ hat
    drawBitmap(bmp);
}   // <=== bmp is disposed here

这对任何 C++ 程序员来说都应该很熟悉 :)

【讨论】:

    【解决方案2】:

    当您的应用程序中不再引用托管对象时,垃圾收集器将全部销毁托管对象。

    在您的情况下,如果您的函数没有将您的对象分配到其他地方,那么一旦您的函数返回,它将被缓冲以进行垃圾回收。

    【讨论】:

      【解决方案3】:

      是的,因为一旦分配给该内存的变量超出范围,正常工作的垃圾收集器就会删除动态分配的内存。例如,在 Java 中,您可以这样说:

      button.addActionListener(new ActionListener() {
          public void actionPerformed(ActionEvent e)
          {
              // do something.
          }
      });
      

      一旦超出范围,“ActionListener()”就会被删除。我在这里只提到 Java 是因为它的垃圾收集属性,并意识到这是一个 C++ 问题。我只是用它来解释一个概念。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-04-01
        • 2010-10-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多