Closed Limgayoung closed 3 months ago
코드 7-1의 스택은 메모리를 직접 관리하기 때문에 null 처리로만 참조를 해제할 수 있는 것 같은데, 스택의 객체가 비활성 영역이 되었다는 것을 자동으로 가비지 컬렉터에 알릴 수 있는 방법은 없나요?
GC의 관점에서는 Object[] elements = new Object[MAX_CAPACITY]
로 객체 배열이 생성되면 객체 배열 전체를 활성화된 객체로 인지합니다.
이를 이해하기 위해서는 GC가 어떻게 동작하는지 볼 필요가 있습니다.
GC는 각 객체들을 도달 가능성(reachablity)으로 분할합니다.
이때 reachable은 프로그램의 실행 흐름 상에서 해당 객체의 주소에 도달 가능하다는 것을 나타냅니다. 즉 어떤 객체가 다른 객체를 참조하는 상태를 의미합니다.
unreachable은 반대로, 어느 시점에서 해당 객체에 대한 참조가 사라져 더 이상 해당 객체에 도달이 불가능하다는 것을 의미합니다.
이때 GC는 메모리를 정리할 때 여러 알고리즘을 사용하며 각 JVM마다 사용하는 GC 알고리즘이 다른 것으로 알고 있습니다. 하지만 일반적으로 먼저 reachable한 객체들을 모두 파악한 뒤, unreachable로 판정된 객체들을 모두 삭제하는 방식으로 진행됩니다.
문제는 위의 element 배열의 경우 배열 객체 자체는 도달 가능성을 판단할 수 있으나 어디부터 어디까지 활성화 되어있고, 비활성화 되었는지는 알 수 없습니다.
따라서 비활성 영역이 되었다는 것을 자동으로 알릴 수 있는 방법은 없을 것으로 생각됩니다. 다만 다른 방식을 통해 해제할 수는 있습니다.
public class Stack {
private Object[] element;
private static final int DEFAULT_CAPACITY = 16;
private int size = 0;
public Object pop() {
if(size == 0) {
throw new EmptyStackException();
}
Object result = elements[--size];
Object[] temp = new Object[size];
for(int i = 0; i < size; i++) {
temp[i] = createElement(element[i]); // element[i]의 내부 값들을 이용하여 새로운 객체 생성 및 반환
}
element = temp;
return result;
}
}
38페이지를 보면 변수의 범위를 최소가 되게 정의했다면 참조를 담은 변수를 유효 범위 밖으로 밀어내는 것이 자연스럽게 이뤄진다고 나와 있습니다. 코드 7-1의 스택은 메모리를 직접 관리하기 때문에 null 처리로만 참조를 해제할 수 있는 것 같은데, 스택의 객체가 비활성 영역이 되었다는 것을 자동으로 카비지 컬렉터에 알릴 수 있는 방법은 없나요?