import java.util.Arrays;
import java.util.EmptyStackException;

public class Stack<T>
	private  T[] elements;
	private static final int DEFAULT_SIZE = 16;
	int size = 0;

	@SuppressWarnings("unchecked")
	public Stack() {
		elements = (T[]) new Object[DEFAULT_SIZE];
		
	}

	public void push(T e) {
		ensureCapacity();
		elements[size++] = e;
	}

	public T pop() {
		if (elements.length == 0) {
			throw new EmptyStackException();
		}
		return elements[--size];
	}

	private void ensureCapacity() {
		if (elements.length == size) {
			elements = Arrays.copyOf(elements, 2 * elements.length + 1);
		}

	}
}

왠만하면 예제같은건 직접 만들려고 헀으나 이건뭐 너무 평범한 코드라 다른 예제를 만들어도 차이가 없을거 같아요..
어쨋든 위의 코드에서 메모리 릭이 발생하는데 왜 발생할까요?
자바는 GC하는데 메모리 릭이 어딧음? 이라고 할수도 있겠지만 분명 자바에도 메모리 릭이 발생합니다.
논리적으로는 사용하지 않는 객체이지만 어딘가에서 참조를 하고있는거죠

위의 코드에서도 그런 현상이 발생합니다. 만약 push를 100번 한다음 pop를 100번 했다면 elements 배열에 들어있는 객체는 몇개일까요?
0개! 라고 당당히 말하면 안됩니다.
정답은 100개입니다.
pop을 하면서 배열내에 있는 객체의 참조를 해제하지 않았기 때문입니다. 인덱스만 주면 얼마든지 꺼내서 쓸수 있다는거죠
물론 캡슐화된 클레스이기 때문에 그런일은 발생하지 않을테지만 만에 하나라는건 항상 존재하죠

다시말해서 GC는 자신을 참조하지 않는 클레스를 청소하는 작업인데 위의 스텍에서는 논리적으로는 분명 스텍의 최상단에서 객체를 꺼냈다. 라는 의미로 구현했지만 배열의 인덱스만 변했을뿐 내용물은 사라지지 않은겁니다. 물론 100개정도야 아무것도 아니겠죠
예를들어 사진을 읽어와서 저장하는 객체가 1000개쯤 쌓였다고 생각해봅시다.
하나에 50kb만 되어도 1000개면 50mb, 10000개면 500mb입니다. 나는 분명히 스텍에서 꺼내서 썼고 그다음 참조를 해제했으므로 GC가 될거라고 예상하고 프로그래밍을 하겠지만 수십메가 단위로 메모리 릭이 생겨버린겁니다.

이것을 해결하기 위해서는 pop에서 몇줄만 바꾸면 됩니다.

	public T pop() {
		if (elements.length == 0) {
			throw new EmptyStackException();
		}
		T e=elements[size];
		elements[--size]=null;
		return e;
	}

이렇게 바꿔주면 됩니다.
이렇게 되면 정말로 배열에서 값을 꺼낸다음 참조를 해제 했기 때문에 스택의 맨 위에서 동전을 꺼낸다는 논리와 정확히 일치하게됩니다.
게다가 혹시 정말 만약에 꺼내졌었던 위치의 객체가 다시 꺼낸다 하더라도 null이 나오기 때문에 NullPointerException이 떠서 에러를 빨리 찾을수 있습니다.

또하나 메모리 릭이 발생하는 경우는 캐시를 하는경우인데. 빨리 읽고 쓰기 위해서 HashMap에 집어넣어두었다거나 하는 경우에 필요없어졌을때 제거를 하지 않게되면 HashMap에 들어있는것을 까맣게 잊고 내버려 두기때문에 결국 메모리 릭이 발생하게됩니다.
이런경우는 WeakHashMap 를 쓰면된다고 합니다.
혹시 나중에 필요하면 WeakHashMap 에 대해서 알아보도록 합시다.

또다른 이유로는 Lisntner과 Callback 이라고 하는데요
Listner는 별생각없이 addListner을 이용해서 계속 넣기만하고 안뺐을때 생긴다고 예상되고
callback은 뭔말인지 잘모르겠습니다. 주석에는 Listner=Callback 이라는 말도 하는거 같은데요

Posted by 동적할당
: