0

I have a code like this:

public class ViewModel01
{
    public ObservableCollection<MyType> MyProperty;
}

Public class ViewModel02
{
    ObservableCollection<MyType> MyProperty;


    Public ViewModel02()
    {
        ViewModel01 myViewModel = new ViewModel01;
        MyProperty = myViewModel01.MyProperty;
    }
}

My doubt is if in the constructor of the second view model, the object myViewModel is recollected by garbage collector or it still keep alive meanwhile ViewModel02 is still alive because I have a reference to the property of view model 01. Or perhaps the view model 01 is collected because really I have a reference to the ObservableCollection, not to the view model 01, so view model could be collected by garbage collector.

Also, I would like to know if there is some way to check if one object is collected or not. I am using visual studio 2019 community.

Thanks.

Álvaro García
  • 18,114
  • 30
  • 102
  • 193

2 Answers2

3

If you really really want to know if you're leaking an object, you could try tracking the live count manually; something simple like the following usually works:

class Foo
{
    static int s_liveCount;
    Foo() => Interlocked.Increment(ref s_liveCount);
    ~Foo() => Interlocked.Decrement(ref s_liveCount);
    public static int LiveCount => Thread.VolatileRead(ref s_liveCount);
}

This only tells you about the type as a whole, though; tracking individual objects is messier because the moment you try - you kinda stop it being collected, unless you go indictectly via WeakReference, etc.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
1

Yes, myViewModel01 should be collected by GC, because there's no reference to it. Observable collection is not collected, as ViewModel02 holds reference to it.

You could test it like that:

public class ViewModel01
{
    private readonly Guid _id;

    public ViewModel01()
    {
        _id = Guid.NewGuid();
        Console.WriteLine($"Constructing {_id}");
    }

    ~ViewModel01()
    {
        Console.WriteLine($"Destructing {_id}");
    }

    public ObservableCollection<MyType> MyProperty;
}

static void Main(string[] args)
{
    var model102 = new ViewModel02();
    GC.Collect(); // Force GC to collect garbage
    Console.ReadKey();
}

You will see in output that that ViewModel01 was constructed and then destroyed.

Alexander Goldabin
  • 1,824
  • 15
  • 17
  • 1
    It may be worthwhile highlighting that calling `GC.Collect` does not _guarantee_ that the line will be written to the console **straight away**. – mjwills Jan 13 '20 at 12:29