Skip to Main Content

Java Programming

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Memory leak caused by cloning a non static inner class (fun)

Alex GellerApr 20 2012 — edited May 4 2012
Hi,
I stumbled upon this one while searching for leak and the cause was not obvious to me at first. I am certain that is it known to the gurus but some other average guys like myself may not roll their eyes at first glance.

The leak chain is as follows current->data->this$0->first item of the list->next->next->…current.

Making <i>Data</i> a static inner class of course solves the issue but I find that scary because I will have to remember for all times that I may not make non static inner classes in this particular class.
</br/>
Shouldn’t the advice even be “Don’t use cloneable non static inner classes at all”? I know that some will take it ever further and say "don't use non static inner classes" or even "don't use inner classes" but I personally like inner classes and I never had problems using them that I wouldn't have had if I had used regular classes instead.

In my particular case I needed a non static inner class so that I resorted to doing it like in C++ where you have to have this$0 explicitly. My “copy constructor” is a clone function that takes the new enclosing instance as an argument.
Regards,
Alex
/*Run this with -Xmx5m */
public class CloneTest implements Cloneable
{
    public static void main(String[] args) throws Exception {
        Runtime runtime = Runtime.getRuntime();
        Node previous=new Node();
        for(int i=0;i<1000000;i++) {
            Node current=previous.clone();
            previous.setNext(current);
            previous=current;
            if(i%1000==0) System.out.println("free memory: " + runtime.freeMemory() / 1024);
        }
    }
    public static class Node implements Cloneable
    {
        Node next;
        Data data=new Data();
        void setNext(Node next) {
            this.next=next;
        }
        public Node clone() throws CloneNotSupportedException {
            Node clone=(Node)super.clone();
            clone.data=data.clone();
            return clone;
        }
        private /*static*/ class Data implements Cloneable {
            public Data clone() throws CloneNotSupportedException {
                return (Data)super.clone();
            }
        }
    }
}
Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Jun 1 2012
Added on Apr 20 2012
49 comments
1,746 views