3

In C#, when I have two object obj1, obj2 composed of a List<string> and I assign both of those objects to the same List<string> object.

If my reference to obj1 goes out of scope but my reference to obj2 does not, is obj1 still eligible for garbage collection, or are there some dependency issues because there is still a reference to the List<string> object?

Matt
  • 4,318
  • 1
  • 27
  • 28
user623879
  • 4,066
  • 9
  • 38
  • 53
  • 8
    +! Good question, but would you please write it out in code? – harpo Jul 04 '11 at 01:46
  • 1
    Seems like a good question, but I'm not really sure because it's not clear what's going on with *obj1*, *obj2*, and the List objects... can you clarify? – Matt Jul 04 '11 at 06:13
  • The accepted answer here seems all wrong. Even though this was forever ago. Sounds to me like the OP described something like this: `var list = new List(); object obj2 = list; { object obj1 = list; }`. Garbage collection doesn't affect variables. It affects objects. `obj1` and `obj2` do not get garbage collected. They exist on the stack and get cleaned up when the function or method returns. The instance first assigned to `list` is the only real object here and that can't be garbage collected until all references to it are destroyed (by going out of scope, or by garbage collection). – bambams Dec 01 '21 at 17:07

5 Answers5

1

obj1 should be eligible for garbage collection as long as there are no references to obj1 itself.

Mrchief
  • 75,126
  • 20
  • 142
  • 189
1

If my reference to obj1 goes out of scope, but my reference to obj2 does not, is obj1 still eligible for garbage collection, or is there some dependency issues because there is still a reference to the List object?

If I understand you correctly you mean both obj1 and obj2 are of type List<string> and both point to the same List<string> instance.

When obj1 goes out of scope, there still will be still obj2 as an active reference to the List<string> instance, so the list cannot be garbage collected.

If obj1 was part of a reference type on the heap (i.e. one of its properties) the memory space it occupied may be garbage collected as part of the outer object. If it was just a reference on the stack, GC will not be involved since the stack will be just unwound at the end of the method call when obj1 falls out of scope.

Keep in mind that obj1 is just a reference (in a way a pointer) to an object on the heap - this object may be garbage collected only when no reference is pointing to it anymore.

BrokenGlass
  • 158,293
  • 28
  • 286
  • 335
0

In your case, obj1 must be eligible for garbage collection.

You need to look at Jon Skeet's answer here. It clearly explains how garbage collection works on object references.

A nice tutorial for you on Object's Lifetime in C#.

Community
  • 1
  • 1
Saurabh Gokhale
  • 53,625
  • 36
  • 139
  • 164
  • Jon Skeet said, in his answer, "An object won't be garbage collected until it's no longer referenced by anything." In this case `obj1` and `obj2` reference the same object. So it is not eligible for collection. – Enigmativity Dec 01 '21 at 20:35
0

There are three uses of memory defined in this question:

  • a reference to the single List<string> instance called obj1.
  • a reference to the single List<string> instance called obj2.
  • The single instance of List<string>.

if obj1 goes out of scope, but obj2 does not, then only the following remain after garbage collection:

  • a reference to the List<string> instance called obj2.
  • The instance of List<string>.

It is important to remember that C# abstracts away the concept of references in most cases so that you can safely think of obj1 and obj2 as being List<string> and not references, but reference they are.

It is likely that the obj1 reference is in the local call stack as opposed to the instance itself which is likely on the heap. Therefore obj1 (the reference) is only cleaned up when the call stack is unwound.

Enigmativity
  • 113,464
  • 11
  • 89
  • 172
-1

If obj1 is a member of a List, it's not available for garbage collection until the parent List is garbage collected.

So:

List<string> l = new List<string>();

string a = "one";
l.Add(a);

{
    string b = "two";
    l.Add(b);
}

At the end of this listing, a is in scope, b is out of scope, but both still have references in the list l, so neither are eligible for garbage collection.

JT.
  • 469
  • 6
  • 9