0

I was writing my own linked list implementation as follows, when I tried to perform operation 'deleteElementFromHead' of the linkedlist, I was curious that what I did was enough or not? The method for deletion of element from head is as follows,

public void deleteAtHead()
{
        Node secondNode = this.head.next;
        this.head = secondNode;
        count--;
}

I am in doubt that while exchanging the pointers to delete element at head, the old head element is still in the memory, and may or may not be collected by the garbage collector. Do I need to set that deleted element to null, or need to add some other piece of code in the above method to avoid memory leak.

The complete code piece for the linkedlist is as follows,

package com.nobalg.Linkedist;

public class Node implements Operations {
int data;
Node next,head,tail;
int count = 1;
public Node(int data)
{
    this.data = data;
    this.head=this;
    this.tail = this;
}

/**********This method takes O(n) time************/
public void addNode(int nodeData)
{
    Node node =  new Node(nodeData);
    Node temp = this;
    while(temp.next!=null){
         temp = temp.next;
    }
    temp.next = node;
    count++;
}

/******This operation takes O(1) time********/
public void addAtTail(int nodeData)
{
    Node node = new Node(nodeData);
    tail.next = node;
    tail = tail.next;
    count++;
}

/********This operation takes O(1) time**************/
public void addAtHead(int nodeData)
{
    Node node = new Node(nodeData);
    node.next = head;
    this.head = node;
    count++;
}

/************This operation takes  O(n) time****************/
public void addAtIndex(int index,int nodeData)
{
    if(index < 0 || index >count)
    {
        throw new IllegalStateException();
    }
    Node node =  new Node(nodeData);
    Node tempLast = this.head;
    Node tempCurrent = this.head;
    int locCount = 0;
    while(locCount!=index){
        tempLast = tempCurrent;
        tempCurrent = tempCurrent.next;
        locCount++;
    }
    node.next = tempCurrent;
    if(index == 0)this.head = node;
    else tempLast.next = node;
    count++;
}

/**********This operation takes O(n) time in case of singly linked list*************/
public void deleteAtTail()
{
    Node temp = this.head;
    Node locLastNode = null;
    while(temp.next!=null)
    {
        locLastNode = temp;
        temp = temp.next;
    }
    this.tail = locLastNode;
    locLastNode.next = null;
    count--;
}

public void deleteAtHead()
{
    Node secondNode = this.head.next;
    this.head = secondNode;
    count--;
}

public void deleteAtIndex()
{
    //implementation pending
}
public int size()
{
    return count;
}

public void display()
{
    Node temp = this.head;
    for(int  i = 0 ; i < count; i++)
    {
        System.out.println(temp.data);
        temp = temp.next;
    }
}
  }
nobalG
  • 4,544
  • 3
  • 34
  • 72
  • if the object has no reference anywhere, it will eventually be garbage collected. – Ajjo Jan 06 '18 at 09:38
  • Why does each node have a next, head and tail element? [LinkedLists](https://www.cs.cmu.edu/~adamchik/15-121/lectures/Linked%20Lists/linked%20lists.html) – Zachary Jan 06 '18 at 09:40
  • IMHO, only the very first node should be head, and the last node has to be tail. – zlakad Jan 06 '18 at 09:44
  • @zlakad yea right, the problem here is that my each node knows that what the head and the tail is :p – nobalG Jan 06 '18 at 11:33
  • @Zachary do i need to create a separate class for it? see [this](http://www.java2novice.com/data-structures-in-java/linked-list/singly-linked-list/) – nobalG Jan 06 '18 at 11:40
  • @nobalG It's down to personal preference. I would have a class for the data structure itself (LinkedList) and another for the nodes of data (LinkedNode). The LinkedList keeps record of the head (and tail if you want), and provides methods to insert, remove, etc. Each node only really needs to know two things: the data and what's next. – Zachary Jan 06 '18 at 11:41
  • 1
    @Zachary Yea, makes sense.. – nobalG Jan 06 '18 at 11:42
  • O.K. Good luck (it seems to me that I'm not allowed to discus here any more - see the comments in one of these answers). Cheers, man. – zlakad Jan 06 '18 at 12:00
  • 1
    @zlakad I have checked already my friend, don't take that to your heart, I wouldn't blame Ravi either, this community have some Passionate people. So some times it happens. You were right in making your points. Your whole discussion cleared many doubts which I had, and it will also help others to learn too, Kudos to you. – nobalG Jan 06 '18 at 12:07

5 Answers5

0

I guess you missed one of the case when tail and head are pointing to the same node. Suppose there is only one element and and you call the deleteAtHead(). In that case the Node has two reference one is head and another is tail and you are only de-referencing the (this.head = secondNode; count--;) head node, What about the tail node. Isn't it still referencing the first node. Here the your program breaks. You should consider the case. If any object has zero reference then you don't need to worry about that object, GC will collect/free that object. But you need to make sure you are de-referencing all those objects properly.

MD Ruhul Amin
  • 4,386
  • 1
  • 22
  • 37
0

The garbage collector automatically runs in the background of JVM. If a resource is not alloted to any variable or not given any reference it gets cleaned by the garbage collector.

Below is the code for deletion at a position.

    Node deleteAtIndex(Node head, int position) {
        Node temp = head;
        if(head == null)
            return null;
        else if(position == 0){
            head=head.next;
        }
        else{
            int currentIndex = 0;
            while(temp != null && currentIndex <= position-2){
                currentIndex++;
                temp=temp.next;
            }
            Node temp2 = temp.next.next;
            temp.next=temp2;
        }
        return head;
    }
HariUserX
  • 1,341
  • 1
  • 9
  • 17
0

the old head element is still in the memory, and may or may not be collected by the garbage collector. Do I need to set that deleted element to null, or need to add some other piece of code in the above method to avoid memory leak

So, you need to understand this, JVM takes care of GC, you don't have much control there. Also, setting null doesn't mean you get allocated memory back immediately.

For example :

Object obj = new Object ();

Creates an object and allocate\reserve memory in JVM. Now, setting obj=null means obj has null reference, but whatever memory was allocated still exist with no reference (and eligible for GC).

Ravi
  • 30,829
  • 42
  • 119
  • 173
  • Yes, but setting an obj to null will HELP GC... (less analyzing) – zlakad Jan 06 '18 at 09:49
  • @zlakad So, am I saying not to set ? I explained what happens when you set null. – Ravi Jan 06 '18 at 09:50
  • Don't misunderstand me, in this question lies the 'trick' - I think he should set all un-referenced Nodes to null. – zlakad Jan 06 '18 at 09:53
  • @zlakad I don't know what are you saying. I answered to the question, which I quoted in my post. I didn't addressed all right now. – Ravi Jan 06 '18 at 09:56
  • He is wondering will it be enough to de-reference Node, or de-reference AND set to null. I'm talking about performance - if an Object has no reference it will be collected, but if Object is ALSO set to null it will be collected more efficiently. – zlakad Jan 06 '18 at 10:01
  • @zlakad what do you mean by more efficiently ?? what are you talking I don't understand. There is nothing like efficient GC. If object has no reference or no longer used, then it is eligible for GC. – Ravi Jan 06 '18 at 10:10
  • This is original code: ` private E unlinkLast(Node l) { // assert l == last && l != null; final E element = l.item; final Node prev = l.prev; l.item = null; l.prev = null; // help GC last = prev; if (prev == null) first = null; else prev.next = null; size--; modCount++; return element; }` – zlakad Jan 06 '18 at 10:13
  • @zlakad don't post code in comment, tell what exactly you are trying to say ? – Ravi Jan 06 '18 at 10:14
  • In the comment above stays a COMMENT //help GC – zlakad Jan 06 '18 at 10:16
  • @zlakad what are you telling I don't understand.. code posted isn't OP's question and even I doubt, if you even have any idea about what you are saying from last few minutes. You are misleading the conversation and post to nowhere. Just answer me, does java have efficient and non-efficient GC ?? Yes or No – Ravi Jan 06 '18 at 10:18
  • @zlakad LOL. take the conversation to nowhere and tell *is it alright with you*. :D I had no intention to make the conversation in my way instead making it clear with what I said and what you understood. Anyway, this is my last comment. – Ravi Jan 06 '18 at 10:24
0

In exchanging of pointers

Node secondNode = this.head.next;
this.head = secondNode;
count--;

in code snippet above, the old element still remains in memory and this is the case of dangling pointers. And for your question how to free the memory from heap refer this question

You can also write this in one line this.head = this.head.next and JVM will most probably take care of GARBAGE COLLECTION...

However, stick with the two line you wrote. It is a better approach.

Hope this helps :)

Akash Chandra
  • 375
  • 1
  • 4
  • 13
0

Below code of yours

public void deleteAtHead()
{
        Node secondNode = this.head.next;
        this.head = secondNode;
        count--;
}

has some of the edge cases missing, like it will throw NPE, when LL is empty and other is when it has just 1 node. anyway your question is below :-

I am in doubt that while exchanging the pointers to delete element at head, the old head element is still in the memory, and may or may not be collected by the garbage collector. Do I need to set that deleted element to null, or need to add some other piece of code in the above method to avoid memory leak.

So yes, in this case, old head element would still be in the memory, but it won't be pointing to the head of your LL, so you won't get the wrong result. and after sometime when GC runs then it would be collected by it, whether you set it to NULL or not.

Read more about what happens when you explicitly assign NULL to a refrence in this SO answer :- Does assigning objects to null in Java impact garbage collection?

Amit
  • 30,756
  • 6
  • 57
  • 88