12

我有一个本机对象 (C++),它有一个gcroot指向托管对象 (C#) 的指针。

class SomeNativeClass {
    gcroot<SomeManagedClass ^> managedClass;
};

问题delete(someNativeClass)当我在以前分配 的本机代码中删除此类的本机实例时,该managedClass实例是否会被垃圾收集,或者我是否也应该显式删除它(在本机析构函数中)?

4

1 回答 1

9

如果只删除本机对象并且在其他任何地方都没有引用托管对象,它会被垃圾收集吗?

这就是垃圾回收的本质。收集器在找不到对象的引用时会销毁该对象。当您使用 gcroot<> 模板类时,它的完成方式略有不同,收集器查找托管对象引用的“正常”方式是通过在 cpu 寄存器和托管代码堆栈和托管堆中发现它们。这在本机代码中不起作用, gcroot<> 类可以提供帮助。

gcroot<> 构造函数调用 GCHandle::Alloc() 来分配对该对象的显式引用。它的析构函数调用 GCHandle::Free() 来删除它。能够分配这些“跟踪句柄”是 CLR 中的次要机制,它为它们维护一个表,除了它自己找到的引用之外,收集器还会参考该表。

最终效果是当你的类析构函数运行时,它会自动调用 gcroot<> 析构函数。对象引用消失了。如果那是唯一的引用,在这种情况下很可能,下一次垃圾收集扫描会破坏该对象。自动地。之后。

于 2012-06-16T21:26:15.233 回答