托管c ++的垃圾收集器

时间:2014-10-30 18:55:56

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

通常在带有指针的C ++中,如果要创建一个动态对象以作为参数传递给函数,它将完成类似

的操作
Object *myObj = new Object;
someFunction(myObj);
delete myObj;
myObj = nullptr;

而不是

someFunction(new Object);

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

someFunction(gcnew Object);

3 个答案:

答案 0 :(得分:3)

    someFunction(gcnew Object);

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


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

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

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

但这不是正确的代码,它不是例外安全的。当 drawBitmap 引发异常时,将绕过 delete 操作员调用。不是世界末日btw,这实际上并没有导致泄漏,因为GC最终清理它。仍然不愉快,所以C ++ / CLI设计者想出了一个原生C ++ RAII模式的模拟,称为#34;堆栈语义"在C ++ / CLI中:

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

对于任何C ++程序员来说,这应该是熟悉的:)

答案 1 :(得分:0)

当应用程序中没有对它进行引用时,垃圾收集器会破坏托管对象。

在这种情况下,如果你的函数没有在其他地方分配你的对象,那么一旦你的函数返回,它将被缓冲为垃圾收集。

答案 2 :(得分:0)

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

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

和&#34; ActionListener()&#34;一旦超出范围就被删除。我之前只提到Java,因为它的垃圾收集属性并且意识到这是一个C ++问题。我只是用它来解释一个概念。