프로그래밍/JAVA2009.06.24 14:04
SUN JVM의 Heap은 Old Generation(Tunured space라고도 불림)과 Young Generation으로 구성되어 있다. Young Generation은 다시 Eden과 두개의 Survivor Space(From Space, To Space)로 나누어 볼 수 있다.


Heap 영역의 동작 과정을 간략하게 살펴 본다면 보통 Object는 Eden에서 생성되며 Eden이 Full이 될 때 Live Object는 From Space로 Copy된다. 다시 Eden이 Full이 되면 From Space에서 To Space로 이동된다. 그리고 Eden이 다시 Full일 때, Object가 사용되거나 참조되고 있는 상태라면 Object는 Old Generation으로 이동하게 된다.


Object는 Eden에서 생성이 되고 Eden이 꽉 차게 되면 Memory copy가 발생한다고 하였다. 이러한 작업을 Minor Garbage collection이라 하고 Copy collenction이라고도 한다. Minor Collection시 Garbage Collector는 Eden의 Object를 검사하여 Reference가 없는 것 들은 제거하고 나머지 live Object는 From space가 꽉 찰 때까지 Eden에서 From Space로 이동하게 된다. 이러한 작업은 짧은 생애를 가질 수 밖에 없는 Object는 최대한 짧게 가지고 있겠다는 SUN  JVM의 특징을 그대로 나타내어 준다.

Eden이 다시 차오르면 From Space의 Live Object는 To Space로 이동한다. 그러나 이것은 논리적으로 그렇다는 것이고 실제로 JVM은 각 Minor collection이 발생할 때 마다 Survivor Space의 포인터를 유지하고 있다가 단순히 From Space에서 To Space로 변경해 주는 것이다. Eden이 다시 full이 되면 To Space에 있는 Live Object는 Old Generation으로 카피된다.

Minor Garbage Collection은 매우 빠르고 효율적이다. 소요시간은 Young Generation의 크기에 따라 다르지만 1초 미만이다. 또한 JVM Thread Processing를 멈추는 등의 부작용도 발생하지 않는다.

Young Generation이 모두 꽉차게 되면 Garbage Collector는 가용 메모리를 확보하기 위해 Major Garbage Collection을 수행한다. Major Garbage Collection은 Object들이 live상태로 있는지 여부를 파악하기 위해 모든 Thread의 수행을 잠시 동결시켜 살아있는 Object를 표시하고 Dead Object는 제거하여 Heap을 정리한다. 이러한 작업 때문에 Major Garbage Collection를 mark and sweep collection이라고도 한다. 이 Major Garbage Collection은 Thread를 잠시 멈추게 되고 Mark and Sweep작업을 위해 CPU에 부하를 가하게 되며 이러한 작업은 보통 Minor Garbage Collection에 비해 10배 이상의 시간을 사용하기 때문에 성능에 악영향을 주게 된다.

SUN  JVM은 앞서 언급한 대로 짧은 운명을 가지고 태어난 Object는 짧게, 그리고 장수할 운명을 지닌 Object는 오래도록 유지시키겠다는 의도를 지니고 있다고 하였다. SUN  JVM을 사용할 때는 이러한 의도를 잘 살려 주는 것이 결국 좋은 성능을 내는 것과 밀접한 관계가 있다할 수 있다. 즉 Short Live Object는 Old Generation으로 올라가기 전에 Young Generation에서 제거되게끔 하고 Long Lived Object의 경우 Old Generation에 상주시켜 상대적으로 아주 저렴한 Minor Garbage Collection만으로 Heap의 유지가 가능하게 유도하는 것이 좋다.

이를 위해서는 JVM의 Memory구성이 중요한데 Young Generation은 전체 Heap의 1/2보다 약간 적게 Survivor Space는 Young Generation의 1/8정도의 크기가 적당하다. 이렇게 Heap을 구성하기 위해서는 별도의 Option을 주어야 한다. JVM의 Default의 경우는 Young Generation이 작게 잡혀있기 때문에 Default를 사용하는 것은 권장하지 않는다. Young Generation이 작으면 short Live Object가 Old Generation으로 넘어갈 확률이 커지고 이는 결국 Major Garbage Collection의 발생확률이 높아지기 때문이다.


JAVA 메모리 대한 주요 옵션은 다음과 같다.

-XX:MaxNewSize=<Value> 
Young Generation의 최대 크기를 지정한다. Young Generation의 시작 크기는 NewSize 옵션에 의해 지정된다.

-XX:NewRatio=<Value>
Young Generation과 Old Generation의 비율을 결정한다. 예를 들어 이값이 2이면 Young:Old = 1:2 가 되고, Young Generation의 크기는 전체 Java Heap의 1/3이 된다.

-XX:NewSize=<Value>
Young Generation의 시작 크기를 지정한다. Young Generation의 크기는 NewSize 옵션(시작 크기)과 MaxNewSize 옵션(최대 크기)에 의해 결정된다.

-XX:PretenureSizeThreshold=<value>
일반적으로 Object는 Young Generation에 최초 저장된 후 시간이 흐름에 따라 Tenured Generation으로 Promotion된다. 하지만, Object의 크기가 Young Generation보다 큰 경우 JVM은 Old Generation에 Object를 직접 저장하기도 한다. PretenuredSizeThreshold 옵션을 이용하면 Young Generation을 거치지 않고 직접 Old Generation에 저장하게끔 할 수 있다. 가령 이 옵션의 값이 1048576(1M)이면, 1M 크기 이상의 오브젝트는 Old Generation에 바로 저장된다. 
큰 크기의 오브젝트를 Old Generation에 직접 저장함으로써 불필요한 Minor GC를 줄이고자 하는 목적으로 사용된다.

-Xms<size>
Java Heap의 최초 크기(Start Size)를 지정한다. Java Heap은 -Xms 옵션으로 지정한 크기로 시작하며 최대 -Xmx 옵션으로 지정한 크기만큼 커진다. Sun HotSpt JVM 계열에서는 최초 크기와 최대 크기를 동일하게 부여할 것을 권장한다. 크기의 동적인 변경에 의한 오버 헤드를 최소화하기 위해서이다.

-Xmx<size>
Java Heap의 최대 크기(Maximum Size)를 지정한다. Java Heap은 -Xms 옵션으로 지정한 크기로 시작하며 최대 -Xmx 옵션으로 지정한 크기만큼 커진다. Sun HotSpt JVM 계열에서는 최초 크기와 최대 크기를 동일하게 부여할 것을 권장한다. 크기의 동적인 변경에 의한 오버 헤드를 최소화하기 위해서이다.

** 모든 JAVA 옵션은 [http://wiki.ex-em.com/index.php/JVM_Options] 참조

'프로그래밍 > JAVA' 카테고리의 다른 글

Java 쓰레드  (0) 2009.12.04
스트러츠 properties 한글 편집  (0) 2009.12.03
Java XML Parser JDOM  (2) 2009.09.03
JRE Detection  (0) 2009.08.11
자바 웹 스타트(Java Web Start)  (0) 2009.08.07
JFreeChart with SWT  (0) 2009.07.14
자바 데몬(daemon) 만들기  (2) 2009.07.08
LRU 캐쉬 엔진의 구현  (0) 2009.06.26
JAVA Memory Leak  (2) 2009.06.25
Out Of Memory Error(OOME)에 대하여  (0) 2009.06.25
JAVA Heap 메모리 모델  (2) 2009.06.24
Posted by devop
TAG ,

댓글을 달아 주세요

  1. 김춘석

    궁금증을 간단 명료하게 설명 해주시네요. 정말 감사합니다.

    2010.03.31 12:34 [ ADDR : EDIT/ DEL : REPLY ]
  2. 잘보고가요

    2018.08.29 14:32 신고 [ ADDR : EDIT/ DEL : REPLY ]