不幸的是,我在整个垃圾收集工作中并不是那么好。现在我不确定如果我做以下事情,我是否会遇到麻烦:
// 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
中还有一个引用?
答案 0 :(得分:1)
系统也不会尝试收集this->m_managedClass->DictProp
,因为它足够聪明地知道另一个gcroot
引用了这个对象。
gcroot
这个聪明的原因是它包装System::Runtime::InteropServices::GCHandle
,它是垃圾收集堆的句柄。 GCHandle
类允许您的非托管对象存储有效的托管引用。此外,即使您的托管对象被垃圾收集器移动,GCHandle
引用也会更新为指向其新位置。