.net C++/CLI在多个根目录托管对象之间交换对象引用

.net C++/CLI在多个根目录托管对象之间交换对象引用,.net,garbage-collection,c++-cli,.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 fi

嗨,不幸的是,我在垃圾收集方面不是很在行。现在我不确定如果我做以下事情是否会遇到麻烦:

// 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();
    }

}
//非托管类
类CUnmagedClass:公共CCmdTarget
{
自动根目录;
自动根管理类;
//在一个根目录中创建第一个管理对象
CUnmagedClass()
:dict(gcnewdictionary())
{}
//用字典做点什么
void AddData(int键,字符串^value)
{
此->指令->添加(键、值);
}
//可以多次调用的方法
void DoOtherThings(数据^Data)
{
//在每次方法调用时创建一个新对象
//旧对象可以被垃圾回收
此->m_managedClass=gcnew SomeManagedClass(数据);
//从另一个根目录分配对词典的引用
this->m_managedClass->DictProp=this->m_dict;
这->m_managedClass->DoSomething();
}
}

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

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

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