JAVA 응용 프로그램이 실행되면 JVM은 시스템으로 부터 프로그램 실행을 위한 메모리를 할당받고
HEAP영역 , Method 영역, Native 영역으로 나누어 관리 한다.
Heap Area : new 명령어로 생성된 인스턴스와 객체가 저장되는 영역
Method Area : 클래스, 변수 Static 변수, Constant 정보 등이 저장되는 영역
- Young generation
대부분의 object들이 존재하는 영역이다. 해당 영역은 작고 자주 collection이 발생한다. 대부분의 object의 수명이 짧기 때문에 해당 영역에서 소멸되는 object이 많다. 해당 영역의 GC는 매우 효율적이고 시스템의 성능에 큰 영향을 주지 않는다
- Old generation
오래동안 살아있는 object들은 해당 영역으로 이동된다. 해당 영역은 일반적으로 young generation보다 더 크기때문에 해당 영역의 GC는 시간이 오래걸린다
Young Generation에서 특정 횟수 이상 참조되면 해당 Object 는 Old Generation 으로 이동하게 된다.
Old Generation 영역의 메모리가 충분하지 않으면 Old Generation에서도 GC 가 발생하는데 이를 FULL GC 하고 한다.
[ 이론적 근거 ]
JVM은 Young Generation 과 Old Generation으로 나뉘는 Generation Heap 구조를 가진다
이러한 구성의 이론적 근거는 Weak Generational Hypothsis 이라
1. 대부분의 Object 는 생성된 후 조기에 Garbage가 되고
2. 살아남은 obect 는 새로운 object를 참조하는 경우가 거의 없다
이를 통해 살아남은 Object만을 잘 관리하면 효율적이라는 원리
[ GC 동작 메카니즘 ]
'x'표시가 된 것이 GC 대상이 되는 object들이다.
Eden에 여전히 살아있는 object들은 From이나 To 중에 한 곳으로 이동한다. ( From과 To는 번갈이가면서 사용된다.)
아래 그림은 To로 이동하는 것을 예로 들었다.
From 영역에 살아있는 object들은 To로 이동한다. 마지막으로 해당 object가 오래동안 살아있다고 판단되는 경우 old generation으로 이동시키게 된다.
오른쪽의 (b)가 GC가 끝난 후의 상태이다. (a)에서는 우측이 비어 있었지만 GC가 끝난 (b)에서는 좌측이 비어있다.
그리고 old generation에 있는 object들은 서서히 증가하게 된다.
여기서 한가지, 각각의 영역이 살아있는 object들을 계속해서 담을 수 있을만큼 크지 않을 수 있다는 것이다. 만약, From/To 영역이 살아있는 object들을 다 담을 수 없을 경우 부족한 만큼이 old generation으로 이동해야 한다. 이러한 현상을 'premature promotion'이라고 한다. 만약, old generation까지 모두 다 차게되면 full GC가 발생하게 된다. 이러한 현상을 'promotion failure'라고 한다
[ 참조 ]
* command line 옵션에는 크게 3가지 종류가 있다.
standard 옵션, non standard 옵션, developer 옵션등이 존재한다.
standard 옵션은 모든 JVM에서 지원하며 JVM이 업데이트 되더라도 어느 정도는 지원되는 옵션이다.
nonstandard 옵션은 -X로 시작하는 옵션들로서 JVM마다 지원하는 옵션들이 서로 다르다.
개발자 옵션은 -XX로 시작하는 것으로서 시스템의 특성에 맞는 동작을 수행하도록 하도록 옵션을 제공한다
- Java < 8
-server
-Xms<heap size>[g|m|k] -Xmx<heap size>[g|m|k]
-XX:PermSize=<perm gen size>[g|m|k] -XX:MaxPermSize=<perm gen size>[g|m|k]
-Xmn<young size>[g|m|k]
-XX:SurvivorRatio=<ratio>
-XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled
-XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=<percent>
-XX:+ScavengeBeforeFullGC -XX:+CMSScavengeBeforeRemark
-XX:+PrintGCDateStamps -verbose:gc -XX:+PrintGCDetails -Xloggc:"<path to log>"
-XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=100M
-Dsun.net.inetaddr.ttl=<TTL in seconds>
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=<path to dump>`date`.hprof
-Djava.rmi.server.hostname=<external IP>
-Dcom.sun.management.jmxremote.port=<port>
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
- Java >= 8
-server
-Xms<heap size>[g|m|k] -Xmx<heap size>[g|m|k]
-XX:MaxMetaspaceSize=<metaspace size>[g|m|k]
-Xmn<young size>[g|m|k]
-XX:SurvivorRatio=<ratio>
-XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled
-XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=<percent>
-XX:+ScavengeBeforeFullGC -XX:+CMSScavengeBeforeRemark
-XX:+PrintGCDateStamps -verbose:gc -XX:+PrintGCDetails -Xloggc:"<path to log>"
-XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=100M
-Dsun.net.inetaddr.ttl=<TTL in seconds>
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=<path to dump>`date`.hprof
-Djava.rmi.server.hostname=<external IP>
-Dcom.sun.management.jmxremote.port=<port>
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false