Memory leak
Take an example:
class Stack { private Object[] elements; private int size = 0; private static final int DEFAULT_INITIAL_CAPACITY = 16; public Stack() { elements = new Object[DEFAULT_INITIAL_CAPACITY]; } public void push(Object e) { ensureCapacity(); elements[size++] = e; } public Object pop() { if (size == 0) throw new EmptyStackException(); return elements[--size]; } public void ensureCapacity() { if (elements.length == size) elements = Arrays.copyOf(elements, 2 * size + 1); } }
This code has a memory leak problem: if a stack grows first and then shrinks, the pop-up elements from the stack will not be garbage collected; even if the stack program does not reference these objects, they will not be recycled
This is because expired references to these objects are maintained inside the stack; expired references are references that will never be released
Possible sources of memory leaks:
- A class that manages its own memory, such as Stack;
- Cache (use weakHashMap or scheduled cleanup by background thread)
- Listeners and other callbacks
Stack is vulnerable to memory leakage because of its own characteristics of managing memory;
Repair: once an object reference has expired, just clean up the references. For the above example, once an element pops up from the stack, the reference to it will expire. The pop method is modified as follows:
public Object pop() { if (size == 0) throw new EmptyStackException(); Object result = elements[--size]; element[size]=null//Eliminate out of date references return result ; }
weakHashMap
import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import java.util.WeakHashMap; public class WeakHashMapTester { static Map<String, String> wMap = new WeakHashMap<String, String>(); static Map<String, String> map = new HashMap<String, String>(); static { String ref1 = new String("obejct1"); String ref2 = new String("obejct2"); wMap.put(ref1, "chaheObject1"); map.put(ref2, "chaheObject2"); } public static void TestWeahHashMap() { System.out.println("WeakHashMap GC before"); for (Entry<String, String> str : wMap.entrySet()) { System.out.println(str); } System.gc(); System.out.println("WeakHashMap GC after"); for (Entry<String, String> str : wMap.entrySet()) { System.out.println(str); } } public static void TestHashMap() { System.out.println("HashMap GC before"); for (Entry<String, String> str : map.entrySet()) { System.out.println(str); } System.gc(); System.out.println("HashMap GC after"); for (Entry<String, String> str : map.entrySet()) { System.out.println(str); } } public static void main(String[] args) { TestWeahHashMap(); System.out.println("---------"); TestHashMap(); } }
Result:
WeakHashMap GC before obejct1=chaheObject1 WeakHashMap GC after --------- HashMap GC before obejct2=chaheObject2 HashMap GC after obejct2=chaheObject2
More: https://stackoverflow.com/questions/6470651/creating-a-memory-leak-with-java/6471947#6471947
Effective java