public 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];
}
private void ensureCapacity() {
if (elements.length == size)
elements = Arrays.copyOf(elements, 2 * size + 1);
}
}
ensureCapacity()
pop
메서드에서 메모리 누수가 발생합니다.ele
배열의 활성 영역
밖의 참조를 하고 있습니다.pop
메서드에서 다 쓴 객체 참조를 null
로 설정하여 GC 가 이를 회수할 수 있게 설정 public Object pop() {
if (size == 0)
throw new EmptyStackException();
Object result = elements[--size];
elements[size] = null; // 다 쓴 객체 참조 해제
return result;
}
elements
에서 size 부분에 대해서 참조 해제를 null
로 수행함잘못된 예시
public class Example {
public void process() {
// 잘못된 예시: 변수를 메서드 시작 부분에 선언
int result;
for (int i = 0; i < 10; i++) {
result = compute(i);
System.out.println(result);
}
}
private int compute(int value) {
return value * 2;
}
}
for 문 안의 하나의 사이클안에서 돌아가는 범위를 가져도 되는
지역변수로 사용되어도 문제없다,for (int i = 0; i < 10; i++) {
// 올바른 예시: 변수를 필요한 범위 내에서 선언
int result = compute(i);
System.out.println(result);
}
WeakHashMap
을 사용해 자동으로 제거되도록 할 수 있음.WeakHashMap
expungeStaleEntries
private void expungeStaleEntries() {
for (Object x; (x = queue.poll()) != null; ) {
synchronized (queue) {
@SuppressWarnings("unchecked")
Entry<K,V> e = (Entry<K,V>) x;
int i = indexFor(e.hash, table.length);
Entry<K,V> prev = table[i];
Entry<K,V> p = prev;
while (p != null) {
Entry<K,V> next = p.next;
if (p == e) {
if (prev == e)
table[i] = next;
else
prev.next = next;
// Must not null out e.next;
// stale entries may be in use by a HashIterator
e.value = null; // Help GC
size--;
break;
}
prev = p;
p = next;
}
}
}
}
e.value = null;
에서 gc 를 동작시킴.