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();
}
}
}
}