Class Reference itself ?

Use this forum for questions on how to use .NET Memory Profiler and how to analyse memory usage.

Moderator: SciTech Software

Class Reference itself ?

Postby Harag » Thu Mar 22, 2018 3:52 pm

Hi
I'm new here and just trialing the memory profiler, so currently learning how to clear up leaks.

I've found a class that is still in memory after I open & close a Win Form. Looking at the instance I get this:

<>9 (MyClassName.<>c) -> #262,221 (MyClassName.<>c)

I think that the .<>c is the "constructor" method, but I don't understand what the first bit means "<>9"

Edit: I have a feeling that the <>9 means it's hold in a static variable, but looking at the code, the class is basically a wrapper around a "grid" control and applied to a panel, however I've removed it from the panel and disposed of the control, so I'm still confused as to why this is still there - however the actual form itself is no longer in memory.

Any help would be appreciated.

Harag
Harag
 
Posts: 17
Joined: Thu Mar 22, 2018 11:22 am

Re: Class Reference itself ?

Postby Andreas Suurkuusk » Fri Mar 23, 2018 10:15 am

Members that include "<>" in the name are usually generated by the compiler. This can for instance be classes used for async calls and enumerators (state machine classes), anonymous types, and auto generated properties.

So in your case, you seem to have a compiler generated class with the name "MyClassName.<>c", with a static field named <>9. The static field contains a reference to an instance of the MyClassName.<>c class.

If you send us a session file or, if possible, the application, we can investigate this further and provide better information. You can contact us at support@scitech.se for information on how to send the session or application (if it's small you can just attach it to the e-mail).
Best regards,

Andreas Suurkuusk
SciTech Software AB
Andreas Suurkuusk
 
Posts: 993
Joined: Wed Mar 02, 2005 7:53 pm
Location: Sweden

Re: Class Reference itself ?

Postby Harag » Fri Mar 23, 2018 11:40 am

Many thanks for that. I've taken a snapshot of before opening the form and after closing. The winform has been removed from the memory so I'm happy that the form isn't leaking, however this one compiler created class is left behind - however no matter how many times I open the form, there is only one instance of this class, it's only taking up 12 bytes - so overall I don't think there is an issue. I'm more curious as to WHY it's there and if it can be removed. I'm fairly new at looking into leaks etc, so trying to understand the information I'm seeing. :)

The file saved is 17MB in size, however the application is massive, so I can send over the session file and explain in the email (and include some code) about what is happening.

Many thanks.

Edit - Email sent, but zipping up the file still keeps it at 17mb. So not sent file. Let me know if you need it.
Harag
 
Posts: 17
Joined: Thu Mar 22, 2018 11:22 am

Re: Class Reference itself ?

Postby Andreas Suurkuusk » Fri Mar 23, 2018 4:27 pm

Thanks for the e-mail. Based on the description and code in the e-mail I can see that the "<>c" instance is an empty closure instance used for the anonymous predicate function in the call to "Where()"

For example, consider the similar code below:

Code: Select all
private void UpdateLabels(string name)
{
    foreach (var label in labels.Where(l => l.Name == name))
    {
        UpdateLabel(label);
    }
}


When this code is compiled, a closure class will be created, containing the function delegate and the captured "name" argument. When making the call to "labels.Where" a new instance of the closure class is allocated. So the code will look something like this:

Code: Select all
private void UpdateLabels(string name)
{
    var closure = new WhereClosure
    {
        name = name
    };

    closure.func = new Func<LabelDef, bool>(closure.Func);

    foreach (var label in labels.Where( closure.func ))
    {
        UpdateLabel(label);
    }
}

private class WhereClosure
{
    public Func<LabelDef, bool> func;
    public string name;

    public bool Func( LabelDef l ) => l.Name == name;
}


However, in your case, you don't have any captured arguments. Your code is similar to:

Code: Select all
private void UpdateLabels()
{
    foreach (var label in labels.Where(l => l.Name == "Label1" ))
    {
        UpdateLabel(label);
    }
}


Since the closure class no longer contains any captured arguments it will always have the same content; a delegate to the "Where" predicate function. As an optimization, the compiler will store this closure instance in a static field, so that it doesn't have to allocate it each time the anonymous method is called.

It is this optimization you see when you have a "left-over" instances of "<>c". So this is not a memory leak.

It is pretty common that data is initialized the first time some code is executed, and some of this data may be cached for future use. This is normally not a memory leak, just normal memory usage. That is why we recommend that you perform an operation once before starting to investigate for memory leaks. E.g.

  • Perform operation (e.g. open and close a Windows form)
  • Collect a snapshot
  • Perform operation again
  • Collect snapshot
  • Look for unexpected new instances that may be part of a memory leak
Best regards,

Andreas Suurkuusk
SciTech Software AB
Andreas Suurkuusk
 
Posts: 993
Joined: Wed Mar 02, 2005 7:53 pm
Location: Sweden

Re: Class Reference itself ?

Postby Harag » Fri Mar 23, 2018 6:05 pm

Hi Andreas,

Many thanks for the detailed reply, really appreciate it. As the number of bytes didn't go up each time I opened/closed the form I didn't think it was really an issue, as I said I was just curious at what the <>9 meant and if I should be concerned if I see more of these - now you've explained it to me, I can look at other areas that have similar rows in the snapshot and disregard them.

Have a good weekend!
Harag
 
Posts: 17
Joined: Thu Mar 22, 2018 11:22 am


Return to Using .NET Memory Profiler

Who is online

Users browsing this forum: No registered users and 8 guests

SciTech Software logo

© Copyright 2001-2016. SciTech Software AB
All rights reserved.


SciTech Software AB
Kartvägen 21
SE-175 46 Järfälla
Sweden


E-mail: mail@scitech.se

Telephone: +46-706868081

cron