컴퓨터 프로그램이 필요하지 않은 메모리를 계속 점유하고 있는 현상이다.
더 이상 불필요한 메모리가 해제되지 않으면서 메모리 할당을 잘못 관리할 때 발생한다.
Java에선 GC(Garbage Collection)이 대부분의 메모리를 관리하여 불필요한 메모리를 해제시켜주지만 몇몇의 경우엔 더이상 사용되지 않는 객체들이 소멸되지 않고 누적되어 Leak이 발생한다.
C언어의 free()라는 함수를 대신하여 JVM의 가비지 컬렉터가 불필요한 메모리를 정리해 주는 것
JVM의 Heap영역은 2가지를 전제로 설계되었다.
1. 대부분의 객체는 금방 접근 불가능한 상태가 된다.
2. 오래된 객체에서 새로운 객체로의 참조는 거의 일어나지 않는다.
Young 영역에 오래되지 않은 객체를 사용이 끝나고 해제시켜준다.
소요시간(대체로 1초 미만)은 Young 영역의 크기에 따라 다르다. JVM을 중지하지 않으며 빠르고 효율적으로 동작한다.
old영역이 크게 할당되는 이유는 큰 객체들은 바로 Old 영역에 할당되기 때문이다.
이러한 상황때문에 Old객체가 Young 객체를 참조하는 경우도 존재한다. 이를 대비하기 위하여 Old 영역에 512 bytes로 되어있는 Card Table이 존재한다.
Old 영역의 객체를 소멸시키는 역할을 수행한다.
Miner GC에서 정리되지 않은 객체가 오래되면 Young 영역에서 Old 영역으로 이동시킨다.
Srop-the-world
모든 Thread를 멈추는 Srop-the-world를 실행하여 참조되지 않는 객체를 Heap에서 소멸시킨다. GC의 성능개선을 하기위해 Thread 중지 시간을 줄이는 작업을 한다.
Mark & Sweep
Stop The World를 통해 모든 작업을 중단시키면, GC는 스택의 모든 변수 또는 Reachable 객체를 스캔하면서 각각이 어떤 객체를 참고하고 있는지를 탐색하여 마킹함
Mark가 되지 않은 객체들을 메모리에서 제거함
무의미한 Wapper 객체를 생성하는 경우
GC는 Immutable 객체를 skip하며 컨테이너 자체가 사라질 때 같이 삭제한다.
StringBuilder와 달리 String과 같은 Immutable객체는 계속 힘에 쌓여 메모리를 점유하는 단점이 있으므로 무분별하게 사용하면 불필요한 메모리를 점유할 수 있다.
Map에 Immutable 데이터를 해제하지 않은 경우
Map에는 강력한 참조가 있어서 내부 객체가 사용되지 않더라고 GC대상이 되지 않는다. Map 내부에 사용하지 않는 데이터는 메모리를 해제하는 것이 좋다.
부실한 Try Catch 설계
try {
Connection con = DriverManager.getConnection();
// 예외 발생 !!!
con.close();
} Catch(exception e) {
}
close하기 전 예외가 발생할 수 있으므로 connection을 close해주는 부분을 catch에서 할 수 있도록 해주거나 별도의 조치를 취해야 한다.
더이상 참조되지 않는 곳의 데이터를 갖고있을 때
stack을 구현했다 가정 시 pop()을 할 때, 기존에 참조하던 메모리의 데이터를 null로 초기화 혹은 삭제 해주지 않는다면 댕글링 포인터가 생길 수 있다.
Java 실행시 GC의 방식, 메모리 크기를 지정할 수 있다.
//힙 영역의 구성을 정의해서 App을 Run하는 예제
java -Xms=256m -Xmx=1536m -XX:NewSize=32m -XX:MaxNewSize=512m -XX:NewRatio=2 App