메모리 진단하기
메모리 때문에 발생할 수 있는 문제
OutOfMemoryError가 발생하는 경우
가비지 컬렉터가 새로운 객체를 생성할 공간을 더 이상 만들어주지 못하고, 더이상 힙 영역의 메모리가 증가될 수 없을때
네이티브 라이브러리 코드에서 스왑 영역이 부족하여 더 이상 네이티브할당을 할수 없을때
두번째 경우는 순수 자바코드를 사용할 때 발생할 확률이 매우 적으며, JNI와 같은 네이티브 라이브러리를 호출하는 소스를 사용할 경우 발생할수 있다.
OutOfMemoryError 메시지 의미
Exception in thread thread_name: java.lang.OutOfMemoryError: Java heap space
- 메모리 크기를 너무 적게 잡아 놓거나, 아에 메모리 크기를 지정하지 않은 경우
- 오래된 객체들이 계속 참조되고 있어서 GC가 되지 않는 경우
- finalize 메소드를 개발자가 개발한 클래스에 구현을 해놓은 경우
- 스레드 우선순위를 너무 높일 경우
- 큰 덩어리의 객체가 여러 개 있을 경우
Exception in thread thread_name: java.lang.OutOfMemoryError: Metaspace
- 너무 많은 자바 클래스가 해당 자바 프로세스에 로딩될 경우
Exception in thread thread_name: java.lang.OutOfMemoryError: Requested array size exceeds VM limit
- 배열의 크기가 힙 영역의 크기보다 더 크게 지정되었을 때 발생한다.
Exception in thread thread_name: java.lang.OutOfMemoryError: request size bytes for reason. Out of swap space?
- 네이티브 힙 영역이 부족할 때 발생하는 메시지다. OS 메모리의 부족한 상황일때가 나타난다 OS에 swap 메모리까지 부족한 경우다
Exception in thread thread_name: java.lang.OutOfMemoryError: reason stack_trace_with_native_method
- 네이티브 힙영역이 부족할때 나타나는 에러 이 경우는 메모리 할당 오류가 JNI나 네이티브 코드에서 발생
메모리 릭의 세 종류
- 수평적 메모리 릭
- 수직적 메모리 릭
- 대각선 형태의 메모리 릭
수평적 메모리 릭
하나의 객체에서 많은 객체를 참조하는 경우(예를 들면 ArrayList와 같은 목록형태나 배열에서 객체를 계속 참조)
수직적 메모리 릭
객체들이 링크로 연결되었을 경우(LinkedList를 사용할 경우)
대각선 형태의 메모리 릭
일반적으로 객체들이 복합적으로 메모리를 점유하고 있는 경우가 여기에 속한다.
OutOfMemoryError 이외의 메모리 문제
OutOfMemoryError 이외의 가장 큰 메모리 문제를 뽑으라고 하면
- 크래시가 발생하는 경우
- 너무 잦은 Full GC
GC를 발생시키지 않으려면
- 임시 메모리의 사용을 최소화
- 객체의 재사용
- xml 처리 시 메모리를 많이 점유하는 DOM 보다 SAX를 사용
- 너무 많은 데이터를 한 번에 보여주는 비지니스 로직 제거
- 기타 프로파일링을 통하여 임시 메모리를 사용하는 부분 제거
GC 모니터링 방법
- 모니터링 도구
- verbosegc 옵션 사용
- jstat 사용