[Mono-bugs] [Bug 485416] New: Anonymous delegate closure functionality may cause serious leaks

bugzilla_noreply at novell.com bugzilla_noreply at novell.com
Sat Mar 14 11:49:27 EDT 2009


https://bugzilla.novell.com/show_bug.cgi?id=485416


           Summary: Anonymous delegate closure functionality may cause
                    serious leaks
    Classification: Mono
           Product: Mono: Compilers
           Version: 2.0.x
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: Normal
          Priority: P5 - None
         Component: C#
        AssignedTo: mono-bugs at lists.ximian.com
        ReportedBy: cdhowie at gmail.com
         QAContact: mono-bugs at lists.ximian.com
          Found By: ---


User-Agent:       Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.0.6)
Gecko/2009020407 Iceweasel/3.0.6 (Debian-3.0.6-1)

If two anonymous delegates are declared in the same method, the variables in
the method scope that are referenced by either delegate magically become
members on a hidden class to implement proper closure functionality. 
Unfortunately, only one class is ever used, carrying the potential of a serious
memory leak if the developer is not careful.  Consider:

--------8<--------
using System;

public class Test {
    public static void Main() {
        object somethingBig = new object();
        int i = 0;

        EventHandler a = delegate {
            somethingBig.GetType();
        };

        EventHandler b = delegate {
            i++;
        };
    }   

    public static void Main2() {
        object somethingBig = new object();

        int i1 = 0;
        int i2 = 0;

        EventHandler a = delegate {
            somethingBig.GetType();
            i1++;
        };

        EventHandler b = delegate {
            i1++;
            i2++;
        };
    }
}
--------8<--------

In the Main method, the set of locals used in the delegates do not intersect at
all.  However, the two locals will both be moved to the same hidden class to
implement the closure.  If something like a large Dictionary<,> is used instead
of a simple object, it will not be garbage collected until either the "local"
is set to null or both delegates are released.  If the second one lives for a
while, it could cause a serious memory overhead, even though this fact is not
obvious, nor intuitive, from reading the code, without understanding how
anonymous delegates are implemented.

The Main2 method is a tad more complex since the intersection of the set of
locals used in each delegate is not empty (they share one local in common). 
Still, it would not be intuitive that keeping the reference stored in the "b"
local alive should keep the object local alive as well.

Reproducible: Always

-- 
Configure bugmail: https://bugzilla.novell.com/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the QA contact for the bug.
You are the assignee for the bug.


More information about the mono-bugs mailing list