我想对 GCHandle.Alloc(Object) 的契约有一个严格的理解。
我从文档中了解到,如果我调用:
GCHandle gc = GCHandle.Alloc(foo);
foo 将保证不会被垃圾收集,直到我调用:
gc.Free();
我还了解到,如果卸载 AppDomain,则 foo 将被收集。
我想检查的是,在不调用 Free 的情况下调用 Alloc 是否实际上与根引用相同(在 GC 看来)。
需要明确的是,如果这是真的,那么 GCHandle 变量 gc 的范围对 foo 的生命周期没有影响。如果 Free 不被调用,则 foo 会一直存在,直到 AppDomain 卸载。
例如
对象对自身调用 Alloc 并且不会保留 GCHandle 实例,它将一直存在到 AppDomain 被卸载为止。
这是正确的吗?
一些参考:
http://msdn.microsoft.com/en-us/library/ a95009h1.aspx
http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.gchandle.free.aspx
http://blogs.msdn.com/b/clyon/archive/2005/03/18/398795.aspx
I'd like to have a rigorous understanding of the contract of GCHandle.Alloc(Object).
I understand from the documentation that if I call:
GCHandle gc = GCHandle.Alloc(foo);
foo will be guaranteed not to be garbage collected until I call:
gc.Free();
I also understand that foo will get collected if the AppDomain is unloaded.
What I would like to check is if a call to Alloc without a call to Free is effectively the same (in the eyes of the GC) as a root reference.
To be clear if this is true then the scope of the GCHandle variable gc has no impact on the lifetime of foo. If Free is not called foo lives until the AppDomain unloads.
E.g.
An object calls Alloc on itself and does not retain the GCHandle instance, it will live until the AppDomain is unloaded.
Is this correct?
Some references:
http://msdn.microsoft.com/en-us/library/a95009h1.aspx
http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.gchandle.free.aspx
http://blogs.msdn.com/b/clyon/archive/2005/03/18/398795.aspx
发布评论
评论(1)
正确的。 GCHandle 变量对传递给 GCHandle.Alloc() 的对象的生命周期没有影响。我使用以下两个类验证了这一点:
以及以下测试代码:
使用此示例,如果您在 Test 类的终结器中设置断点,您将注意到在任何 GC.Collect/WaitForPendingFinalizers 调用期间都不会调用它。但是,当应用程序域被卸载时,就会命中断点。
Correct. The GCHandle variable has no effect on the lifetime of the object that you pass to GCHandle.Alloc(). I verified this with the following two classes:
And the following test code:
Using this example, if you set a breakpoint in the Test class's finalizer, you will note that it is not called during any of the GC.Collect/WaitForPendingFinalizers calls. The breakpoint is hit, though, when the appdomain is unloaded.