What are the challenges you face when working across database platforms? Take the survey

How to interpret the GC->System.Object[]->MyObject path in the Object Instance retention graph.


As demonstrated in the first picture of this example:

....One possible GC retention path is the one that is on the far left in the picture.

It shows GC referencing a System.Object[] (presumably an object array) that is referencing myObject.

I am currently trying to investigate a case in my own application where the memory is not collected. The ONLY reference (with and without the "hide finalizer queue" checked) is GC referencing System.Object[] referencing my object just like the left path of the example picture.
It looks like this:

I don't understand what this is indicative of. What object is this that is referencing my objects? What is this lingering reference?

I expanded the System.Object[] instance within the ANTS profiler and got stuff like this:

It seems that this is some framework stuff, but I don't see how this will help me dereference my object.


  • Options
    Jessica RJessica R Posts: 1,319 Rose Gold 4
    Hi @TormodS,

    Thanks for your post!

    Static variable storage is implemented internally by .NET as object arrays referenced by GC handles, so that is likely what the object array is in this case.

    Jessica Ramos | Product Support Engineer | Redgate Software

    Have you visited our Help Center?

  • Options
    TormodSTormodS Posts: 2 New member
    Thanks for coming back to me.

    So, am I understanding you correctly that I am looking for a static field of type System.Collections.Array<MyNamespace.OmmObjectDataSet>? So going to OmmOjbectDataSet in my code and seeing where it is used should list the culprit?

    What should I do if there is no such field?

    Are there (compiler) optimizations that I can switch off that will help me in finding the culprit?
    For instance that the compiler will not use array under the hood for some other collection type, or that it will not attempt to "use base type where possible" or some such thing?

    For instance, I found that Refactoring to method and preventing inline expansion of that method forced variables out of scope and it significantly changed the ANTS result. This was a variable that was declared in a "using" statement with a subsequent GC.Collect() before snap shot was made, so I didn't expect managed objects to be retained.
  • Options
    Jessica RJessica R Posts: 1,319 Rose Gold 4
    Hi @TormodS,

    Please note: I'm not an expert on .NET internals so you may want to take what I say with a grain of salt!

    From what I understand though, a System.Object[] like this often represents a static field and if it is (I'm not sure if there are other types that are stored in object arrays), then it looks like a static field is referencing your OmmObjectDataSet[] object.

    With that, I would check where OmmObjectDataSet[] is used, particularly by static fields. I'd also check- is there any values in the object array which look related to your code? Or do they all look like internal .NET strings?

    I'm not aware of a compiler option that would prevent arrays being used under the hood unfortunately, and couldn't find anything from some searching. : /

    Jessica Ramos | Product Support Engineer | Redgate Software

    Have you visited our Help Center?

  • Options
    HaragHarag Posts: 8 New member
    edited February 12, 2018 8:44AM

    I'm new here, and just playing around with the trial (day 1 at the moment), and just looking at a couple of my objects and I have a very similar picture with two of my objects


    I have a static class which then has a static method in it:

    public static List<AssetCustomData> FetchAssetCustomData(int assetHeaderId)
    var customDataList = new List<AssetCustomData>();
    ... //Adds objects to the list here from DB.
    return customDataList;

    this method returns the list of objects back to my WinForm.

    However my Winform is now closed, but the "AssetCustomData[]" is still referenced, rest of the form is clean now.

    Any .net people out there that can suggest a better way to do this?

    EDIT 1:
    I've now changed my class to a sealed class, and removed the static from the methods - but I still get the same result in the ANTS memory app.

    EDIT 2: Just done a full recompile of the application, and tested again this morning, still getting the same result. I can say the AssetItem[] is not at all static, but there is still a GC Handle to it through System.Object[]
Sign In or Register to comment.