多个gcrooted托管对象之间的C ++ / CLI交换对象引用

时间:2010-06-29 13:02:37

标签: .net garbage-collection c++-cli

不幸的是,我在整个垃圾收集工作中并不是那么好。现在我不确定如果我做以下事情,我是否会遇到麻烦:

// unmanaged Class
class CUnmagedClass : public CCmdTarget
{
    auto_gcroot<Dictionary<int, System::String^>^> m_dict;
    auto_gcroot<SomeManagedClass^> m_managedClass;

    // create first manage object in one gcroot
    CUnmagedClass()
    :dict(gcnew Dictionary<LANGID, System::String^>())
    {}

    // do something with the dictionary
    void AddData(int key, String^ value)
    {
         this->m_dict->Add(key, value);
    }

    // Method that could be called multiple times
    void DoOtherThings(Data^ data)
    {
         // create a new object on every method call
         // old object can be garbage collected
         this->m_managedClass = gcnew SomeManagedClass(data);
         // assign a reference to the dictionary from the other gcroot
         this->m_managedClass->DictProp = this->m_dict;

         this->m_managedClass->DoSomething();
    }

}

所以我的问题是,如果我覆盖this->m_managedClass中的值并且旧的SomeManagedClass实例被垃圾收集。系统是否也试图收集this->m_managedClass->DictProp中的对象,因为它不再连接到第二个gcroot,或者垃圾收集器是否足够聪明,知道另一个gcroot中还有一个引用?

1 个答案:

答案 0 :(得分:1)

系统也不会尝试收集this->m_managedClass->DictProp,因为它足够聪明地知道另一个gcroot引用了这个对象。

gcroot这个聪明的原因是它包装System::Runtime::InteropServices::GCHandle,它是垃圾收集堆的句柄。 GCHandle类允许您的非托管对象存储有效的托管引用。此外,即使您的托管对象被垃圾收集器移动,GCHandle引用也会更新为指向其新位置。