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

Diego Frata diego.frata at gmail.com
Fri Aug 24 22:44:13 UTC 2012


Answering Stephen's question, mo will have it's Dispose method called if
Foo is garbage-collected and might also be finalized and disposed again (if
IDisposable is not correctly implemented) before finishing executing the
doSomething method.

I was able to reproduce this exact behavior.

Diego Frata
diego.frata at gmail.com


On Fri, Aug 24, 2012 at 7:09 PM, Diego Frata <diego.frata at gmail.com> wrote:

> Sorry guys, I misread the topic and said something very stupid!
>
> Diego Frata
> diego.frata at gmail.com
>
>
>
> On Fri, Aug 24, 2012 at 7:01 PM, Diego Frata <diego.frata at gmail.com>wrote:
>
>> mo actually is this.mo, so you do have a reference for this.
>>
>>
>> Diego Frata
>> diego.frata at gmail.com
>>
>>
>> On Fri, Aug 24, 2012 at 5:47 PM, Lepisto, Stephen P <
>> stephen.p.lepisto at intel.com> wrote:
>>
>>>  Am I wrong in thinking that in****
>>>
>>> ** **
>>>
>>>    void Problem() { mo.doSomething(); }****
>>>
>>> ** **
>>>
>>> "mo" is contained within the context of the method body of Problem() and
>>> therefore cannot be disposed of until the method body of Problem() has done
>>> execution.  This means that "mo" will continue to live for the life of the
>>> call to doSomething() because the Problem() method body holds onto "mo"
>>> until after doSomething() returns.****
>>>
>>> ** **
>>>
>>> ** **
>>>
>>> *From:* mono-devel-list-bounces at lists.ximian.com [mailto:
>>> mono-devel-list-bounces at lists.ximian.com] *On Behalf Of *David Jeske
>>> *Sent:* Friday, August 24, 2012 1:27 PM
>>> *To:* Jonathan Pryor
>>> *Cc:* mono-devel-list at lists.ximian.com
>>> *Subject:* Re: [Mono-dev] Why does .NET object lifetime not extend into
>>> an instance method call?****
>>>
>>> ** **
>>>
>>> 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 usage? ****
>>>
>>>  ****
>>>
>>> ** **
>>>
>>> _______________________________________________
>>> Mono-devel-list mailing list
>>> Mono-devel-list at lists.ximian.com
>>> http://lists.ximian.com/mailman/listinfo/mono-devel-list
>>>
>>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.ximian.com/pipermail/mono-devel-list/attachments/20120824/0a05e49e/attachment-0001.html>


More information about the Mono-devel-list mailing list