-1

Today I checked the memory usage of my application and I found something that does not make sense to me. I expected to have more than one instance of an object that I do not dispose but when I check the diagnosis tool it only has one instance. Then I tried to run some tests to intentionally create more than one instance and check the memory and it was again one.

Imagine we have a class like this.

public class Car
{ 
  public string Name {get;set;}
}

If I create 100 instance of this Car object in a loop I expected to have 100 objects in memory.

for (int i = 0; i < 100; i++)
{
  var car = new Car();
}

But when I try this and check the memory I only see one instance of that object! I tried this with HttpClient too but still the same. I was wondering if I am missing something here and what is the point of CG in that case! I did so many googling and I was not able to find a proper answer so I thought maybe share it with you guys.

Brad Ihc
  • 9
  • 2
  • 4
    you are missing something: _variable scope_. your `var car` only exists for the duration of one loop iteration. afterwards, garbage collection kicks in (simplified) – Franz Gleichmann Apr 21 '21 at 17:11
  • 2
    Each time it loops, the variable `car` goes out of scope, so it doesn't hold onto the instance. It is being garbage collected. This is working as intended. What's the issue? –  Apr 21 '21 at 17:12
  • 2
    You create 100 instances, but they are getting out of scope (and unrooted) immediately – Jcl Apr 21 '21 at 17:12
  • 2
    Your question doesn't contain any unmanaged objects. –  Apr 21 '21 at 17:16
  • 1
    Your objects are being collected before you look for them because they are not reachable after each iteration of the loop and so get collected. If you don't desire this behavior, you need to disable garbage collection. See duplicate. If you do desire this behavior, then the question doesn't really make any sense. The garbage collector's doing exactly what it's supposed to: collecting garbage. – Peter Duniho Apr 21 '21 at 17:49
  • @FranzGleichmann Even when I declare the variable outside of the loop it still wont create more than one instance. Car car; for (int i = 0; i < 100; i++) { car = new Car(); } is this still acceptable? – Brad Ihc Apr 21 '21 at 18:29
  • 3
    because every new car replaces its predecessor... – Franz Gleichmann Apr 21 '21 at 18:43
  • @Jcl What happens when the instances get unrooted? will they stay in memory or they will removed by GC? – Brad Ihc Apr 22 '21 at 06:21
  • @BradIhc a GC root is a reference to an object that must survive the next GC collection. When there are no more GC roots referencing an object (i.e., the object is "unrooted"), that object gets collected (although a bit more internally complicated than that, to put it easy: its memory will be freed) – Jcl Apr 22 '21 at 06:42

1 Answers1

3

what is the point of CG in that case!

Assuming you mean GC (Garbage Collector), the point is the GC is doing it's job! Each of those objects goes out of scope almost as soon you create it*, and so the GC collects it. It's not that the managed objects don't exist, so the GC has nothing to do. It's that the GC has already cleaned them up by the time you can look. This is what "managed" means... the GC takes care of the clean-up for you, so you don't have to worry (as much) about filling up ram with old items.

If you really want to see 100 items, try this code:

Car[] cars = new Car[100]; // declare this outside the loop
for (int i = 0; i < 100; i++)
{
  cars[i] = new Car();
}

*It's probably even worse: the JIT or compiler detects these objects will go out of scope, and never even allocates them.

Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794