Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inner Class has an implicit reference to the outer class and may can leak memory

After learning about the inner class, I understand it has an implicit reference to the outer class.

But my teacher told me that the best way is not use inner class, prefer to use static inner class. Because the inner class may leak memory.

Can someone kindly explain about this?

like image 660
Jie Avatar asked Mar 01 '15 01:03

Jie


1 Answers

In the answer to your comment (it would be unreadable if I posted it in the comments), where it belongs. Example of accesing inner class outside the outer.

public class Dog {
    String name;
}

public class HugeKennel {
    Double[] memmoryWaste = new Double[10000000];


    public List<Dog> getDogs() {
        SneakyDog trouble = new SneakyDog("trouble");
        return Arrays.asList(trouble);
    }

    class SneakyDog extends Dog {
        SneakyDog(String name) {
            this.name = name;
        }
    }

}

somewhere else in your code

List<Dog> getCityDogs() {
    List<Dog> dogs = new ArrayList<>();
    HugeKennel k1 = ...
    dogs.addAll(k1.getDogs());
    HugeKennel k2 = ...
    dogs.addAll(k2.getDogs());
    return dogs;
}

....

List<Dog> cityDogs = getCityDogs();
for (Dog dog: dogs) {
    walkTheDog(dog);
}
// even though the Kenels were local variables in of getCityDogs(), they cannot be removed from the memory, as the SneakyDogs in the list are still referencing their parent kennels.
//from now on, until all the dogs are not disposed off, the kennels also have to stay in the memory.

So you don't need to access the inner class through its parrent class, once the inner object is created it can be used as any other object and can be 'leaked outside' its container class, like in the above example, when the dog list will hold references to dogs, but each dog will still 'know' about its kennel.

The linked example from StackTrace was related to typical use case, when the innner classes are created 'ad hock' as anonymous inner classes, but it is the same problem. If you pass the reference to any instance of an inner class, you are also 'passing' reference to the outer class.

like image 200
Zielu Avatar answered Oct 27 '22 00:10

Zielu