-1

Linked List:

public class ListNode {
     public int val;
     public ListNode next;
     public ListNode(int val=0, ListNode next=null) {
         this.val = val;
         this.next = next;
}
public static void Main(){
     ListNode head = new ListNode(5);
     ListNode curr = head;
     curr.next = new ListNode(6);
     curr = curr.next;
     curr.next = new ListNode(7);
     curr = curr.next;
     curr.next = new ListNode(8);
     curr = null;
}

I created a Linked using above code. head is a ListNode identfier which points to node1 intially. enter image description here After pointing head to node2, will node1 be collected by garbage collector? Note that node1 is not referenced by any identifier now however it's next pointer in heap memory still points to a non-null object?

Edit: As per my understanding GC collects all the free objects that are not in use but here node1 is not completely free since its connected to the linked list which is still in use.

Yasir
  • 121
  • 7
  • So you have reasons why you think that node will not be eligible for GC. Adding that reasoning to the post would greatly help. (In current state it is quite unclear why this question exists). – Alexei Levenkov Aug 10 '22 at 17:40
  • @AlexeiLevenkov As per my understanding GC collects all the free objects that are not in use but here node1 is not completely free since its connected to the linked list which is still in use. – Yasir Aug 10 '22 at 18:31
  • Bear in mind the GC can collect entire graphs containing cycles. Your theory that an *outgoing* reference would keep objects alive would make that impossible. – Damien_The_Unbeliever Aug 12 '22 at 06:07

2 Answers2

1

Unless its reference is held by another object it will be collected. To test it, you can add a finalizer to the node class (doc here: https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/finalizers)

public class ListNode {
     public int val;
     public ListNode next;
     public ListNode(int val=0, ListNode next=null) {
         this.val = val;
         this.next = next;
     }
     ~ListNode()  // finalizer
     {
        Console.WriteLine("Hey, I'm being collected!");
     }
}
public static void Main(){
     ListNode head = new ListNode(5);
     ListNode curr = head;
     curr.next = new ListNode(6);
     curr = curr.next;
     curr.next = new ListNode(7);
     curr = curr.next;
     curr.next = new ListNode(8);
     curr = null;
     //force the garbage collection
     GC.Collect();
     GC.WaitForPendingFinalizers();
    //look at the standard output
}
Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
ddfra
  • 2,413
  • 14
  • 24
  • Please check https://stackoverflow.com/questions/4257372/how-to-force-garbage-collector-to-run (for proper GC call) and https://meta.stackoverflow.com/questions/255644/should-edit-in-edits-be-discouraged (for adding "EDIT:" to posts) – Alexei Levenkov Aug 10 '22 at 19:55
0

Yes, the garbage collector will, when it does a full collection, collect any objects that are no longer referenced. Your node1 would no longer be referenced in your example.

But... In such a simple program the GC will probably never run. In general you rarely need to worry about collecting memory, the main things to worry about regarding memory leaks are:

  1. If you have some kind of list where you add objects but never remove them, a non intuitive example of this are events, that are internally a list of delegates.
  2. Disposing any objects implementing IDisposable. Not disposing such objects may not lead to memory leaks, but should be done to ensure correct function of your program. (with some notable exceptions, like Task)
  3. When dealing with native memory
JonasH
  • 28,608
  • 2
  • 10
  • 23
  • 1
    If you [edit] to highlight difference between incoming and outgoing references it would answer the question OP actually wanted to ask (see they comment). – Alexei Levenkov Aug 10 '22 at 19:29