java에서는 OS의 메모리영역에 접근하여 , JAVA의 메모리를 관리하는 가상의 프로그램인 JVM이 있다.
JVM은 GC(Garbage Collector)가 Memory를 직접 관리한다.
GC는 사용되지 않는 Memory를 탐지해서 해제하는 등의 업무를 한다.
Java에서 Memory는 2가지 (stack, heap) 영역으로 구분되며
Stack은 정적으로 할당된 메모리 (boolean, char, short, int, long, float, double)의 데이터가 값과 함께 할당된다.
그리고 Stack 의 메모리는 Thread당 하나씩 할당된다. 각각의 Thread 끼리는 Stack 영역에 접근할 수 없다.
Heap은 동적으로 할당된 메모리 영역이다. Stack에 쌓이는 변수를 제외하고 대부분 Heap영역에 포함된다.
Heap은 여러개의 Thread가 있어도 힙은 단 하나의 영역에만 존재한다.
public static void main(String[] args){
String name = "seoklee";
name+= " addString";
System.out.println("After Name 1 : " + name);
changeName(name);
System.out.println("After Name 2 : " + name);
}
public static void changeName(String arg)
{
arg+= " addString";
}
console
After Name 1 : seoklee addString
After Name 2 : seoklee addString
결과값은 너무도 당연하게 생각했지만 해당 main함수에서 Memory영역은 어떻게 구성이 되어있을까?
stack에 name이라는 변수가 heap영역의 String :seoklee를 가리킨다.
heap영역에 seoklee addString을 새로 할당하여 String : seoklee addString을 가리키게 한다.
args 라는 stack 영역이 생성되고 heap영역에 2. 와 같이 처리 후 seoklee addString을 가리킨다
heap영역에 args
changeName 함수가 종료된 후 stack영역에 할당된 args가 해제된다.
이 후 Heap영역에 할당된 남은 객체들을 GC가 해제 시킨다.
만약 Heap영역에 엄청나게 많은 객체가 할당된다면.. out of memory (oom)가 발생하게된다.
이런 사태를 방지하기 위해 Heap 모니터링과 Heap Dump를 떠서 분석하는 방법을 생각할 수 있다.
Heap을 관리하여 누수되는 메모리, 낭비되는 메모리를 check 하여 문제를 줄이도록 해야겠다.
정의
명령어
jstack -l {PID} > {파일명}
jstack -l 12342 > jstack_serviceA.txt
jps -v | grep "{serviceName}" | awk '{print $1}' | xargs jmap -dump:live,format=b,file=jdump_restapi.hprof
jmap -dump:live,format=b,file=jdump_restapi.hprof {PID}
jps : Java Virtual Machine Process Status Tool
java의 프로세스 상태를 알아내는 tool
-v : jvm 파라미터 표시
awk : 공백으로 구분된 row를 분석하여 특정 column 정보 출력
xargs : 앞에 출력된 정보를 입력으로 받아 우측에서 명령어로 실행시킴
jmap: -dump 옵션으로 dump를 생성할 수 있음
-dump:live,format=b,file={dumpFileName.hprof}
-----> 즉, jmap -dump:live,format=b,file=jdump_restapi.hprof {PID} 와 같음..