MSDN表示
您还可以使用GCHandle创建固定对象,该对象返回一个 内存地址,以防止垃圾回收器移动对象 在内存中。
当句柄超出范围时,必须通过以下方式显式释放它: 调用Free方法;否则,可能会发生内存泄漏。当你 释放固定的句柄后,关联的对象将被取消固定并将 如果没有其他条件,就有资格进行垃圾收集 引用。
因此,如果将非固定的普通GCHandle创建到名为fooObj的托管类对象,则
GCHandle gch = GCHandle::Alloc(fooObj, GCHandleType::Normal);
是否需要使用Free()释放它?
gch.Free();
还是GC在不需要时将其释放?
我不希望释放它的原因是因为在以下代码中,即使在分配并释放了诸如gch2之类的其他GCHandle之后,我仍需要paramsArgVPtr和gch1继续引用fooObj对象。但是,似乎一旦gch2被释放,尽管gch1仍在引用该对象,但关联对象却被取消固定。无论哪种方式,gch1都会失去对该对象的访问权限。
#include "pch.h"
#include <iostream>
using namespace std;
using namespace System;
using namespace System::Runtime::InteropServices;
ref class Foo // Required to be a managed ref class
{
private:
int a = 0;
};
int main()
{
Foo ^ fooObj = gcnew Foo();
// Get a void pointer that can access the object
GCHandle gch1 = GCHandle::Alloc(fooObj, GCHandleType::Normal);
void * paramsArgVPtr = GCHandle::ToIntPtr(gch1).ToPointer();
// This would happen in an external non-member function that accepts a void * argument paramsArgVPtr
// But I'm putting it here for a minimal example.
GCHandle gch2 = GCHandle::FromIntPtr(IntPtr(paramsArgVPtr));
Foo ^ fooObjCopy = safe_cast<Foo ^>(gch2.Target);
gch2.Free();
// Check to see if the object is still accessible through gch1
if (gch1.Target == nullptr)
{
cout << "gch1 points to a null pointer after freeing gch2" << endl;
}
else
{
cout << "gch1 can still access the object after freeing gch2" << endl;
}
gch1.Free();
}