[Mono-dev] Why does .NET object lifetime not extend into an instance method call?

David Jeske davidj at gmail.com
Fri Aug 24 20:26:40 UTC 2012

On Fri, Aug 24, 2012 at 10:50 AM, Jonathan Pryor <jonpryor at vt.edu> wrote:

> > It seems this could happen in more cases than just PInvoke. This seems
> to allow a finalizer to run before an object is "done being used" anytime
> the object instance is not stored. (i.e. inside a statement of the form
> "new Foo().Method();") If the finalizer triggers an IDispose pattern, this
> could cause a managed resource to be torn down before it's done being used
> as well.
> The managed resource can't be disposed before it's done being used AS LONG
> AS the GC knows about all uses of the managed resource.

... snip ...

The real problem is that the GC doesn't know anything about native code,
> and thus can't ensure that no native code is using the resource.

Thanks very mych for the detailed reply. It seems to me there is a race
that has nothing to do with native code. Consider this example..

class Foo : IDisposable { ManagedObject mo = new ManagedObject(); ~Foo() {
this.Dispose(); } public void Dispose() { if (mo != null) { try {mo.Dispose
();} finally { mo = null; } } } void Problem() { mo.doSomething(); } static
void Main() { new Foo().Problem(); } }

If I understand the MS.NET article, as soon as ms.doSomething enters the
vcall, "this" is no longer referenced. Which means during
ManagedObject.DoSomething, Foo could be finalized, and thus Disposed, and
since the Dispose explicitly Disposes mo, the code would Dispose mo while
it's still inside mo.doSomething(). Did I miss something?

> > Why isn't this considered a bug in the .NET runtime?
> How would you fix it? The .NET runtime has no way of knowing what native
> code is doing, so short of disassembling the native code ("magic"), what is
> .NET supposed to do?

Ohh, I don't think the problem is the way this is handled for native code.
I think the above interaction in IDisposable seems like a problem too. To
me this seems like a pre-mature finalization bug caused because "this"
isn't considered referenced for the entire body of instance methods.

> (2) Does the Mono GC have the same behavior?
> Yes, because there's no other sane behavior.

> However, this can't be relied upon; Linux supports "precise stack
> marking," which prevents conservative scanning of native stack frames. This
> has the wonderful performance advantage that less memory needs to be
> pinned, allowing the GC to be more efficient:
>         http://www.mono-project.com/Generational_GC#Precise_Stack_Marking

I'm sorry for my naivety. Why does allowing unused function arguments to be
collected before a function returns have such important effects on memory
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.ximian.com/pipermail/mono-devel-list/attachments/20120824/f002ea84/attachment-0001.html>

More information about the Mono-devel-list mailing list