Hotspot JVM GC 엑셈컨설팅본부 /APM 팀김정태 개요 본문서는 Hotspot JVM 의 Garbage Collection 에대한기본적인동작방식과 Internal 한내용이포함되어있다. 본문내용을통해 WAS 의 Suspend 현상과 Application Thread, Garbage Collection Thread 간의경합에대해이해하고나아가특정환경에적합한 Garbage Collector 를선택할수있는기본적인지식을제공할목적으로작성되었다. 1. Garbage Collection Heap storage for objects is reclaimed by an automatic storage management system(typically a Garbage Collector); objects are never explicitly deallocated. - Java Virtual Machine Speculation [JVMS2 1999] Heap 은 Object 를위한 Memory 공간이고 Garbage Collector 라고하는자동화된시스템에 의해 Heap 은재사용될수있다. 그리고 Object 는절대명시적으로해제되지않는다. 가. Introduction 앞서본 Garbage Collection 에대한 JVM Speculation 을부연설명을하자면, 이미할당된 Memory 는 Garbage Collection( 이하 GC) 에의해해제가되는데이때 Garbage 는 Heap 과 Method Area 에서사용되지않는 Object 를의미한다. 그리고소스상의 close() 는 Object 사용중지의사표현일뿐 Object 를 Memory 에서삭제하겠다는의미가아니다. 개발자는 System.GC() 를명시적으로사용하여 GC 를발생시킬수있지만이경우에는 Full GC 가발생한다. Part 2 APM 279
나. GC로인한문제점 GC 라는자동화메커니즘으로인해프로그래머는직접 Memory 를핸들링을할필요가없게되었다. 더불어잘못된 Memory 접근으로인한 Crash 현상의소지도없어지게되었으니더없이편리한기능이아닐수없다. 그러나 GC 는명시적인 Memory 해제보다느리며 GC 순간발생하는 Suspend Time 으로인해다양한문제를야기시킨다. 시스템의성격마다 Suspend Time 허용치는각각다르겠지만 GC 튜닝을실시할경우통상 Application 최적화이후 ( 생성오브젝트최소화등 ) 본격적인 GC 튜닝을진행한다. 다. Root Set과 Garbage Garbage Collection 은말그대로 Garbage 를모으는작업인데여기서 Garbage 란사용되지않는 Object 를말한다. 좀더명확히설명하면 Object 의사용여부는 Root Set 과의관계로판단하게되는데 Root Set 에서어떤식으로든 Reference 관계가있다면 Reachable Object 라고하며이를현재사용하고있는 Object 로간주하게된다. [ 그림 1] 최하단 Root Set 에서 Object 를참조하는형태 280 2013 기술백서 White Paper
Root Set 은광의적개념으로서좀더구체적으로말하면아래와같이 3 가지참조형태를통해 Reachable Object 를판별한다. 1. Local variable Section, Operand Stack 에 Object 의 Reference 정보가있다면 Reachable Object 다. 2. Method Area 에로딩된클래스중 constant pool 에있는 Reference 정보를토대로 Thread 에서직접참조하진않지만 constant pool 을통해간접 link 를하고있는 Object 는 Reachable Object 이다. 3. 아직 Memory 에남아있으며 Native Method Area 로넘겨진 Object 의 Reference 가 JNI 형태로참조관계가있는 Object 는 Reachable Object 이다. 위의 3 가지경우를제외하면모두 GC 대상이된다. Reachable but not Live Object 란? Class Main { public static void main (String args[]) { Leak lk = new Leak(); for(int a=0; a<9000000; a++) { lk.addlist(a); lk.removestr(a); } } } Class Leak { ArrayList lst = new ArrayList(); public void addlist(int a) { lst.add( 가나다라마바사아자차카타파하 +a); } public void removestr(int i) { Object obj = lst.get(i); obj = null; } } Array List 에 String Object 를넣고 removestr() 메소드가 Object Reference 변수를찾아 null 로치환 Part 2 APM 281
실행하면 OutOfMemoryException( 이하 OOME) 이발생하면서비정상종료된다. 이유는 obj 변수로받은건 String Object 가아닌 Reference 값이기때문이다. null 로치환돼도 Array List 에들어간 String Object 가사라진건아니며더불어참조변수가없어서이들은앞으로사용되지않을것이다. 이를 Reachable but not Live Object 라고하며이들이많아지면 heap 에 Memory 릭발생했다고표현한다. GC 가수행된 Memory 의해지는할당된그자리에서이루어지며그로인해 Heap 의단편화같은문제가발생한다. JVM 에서는이러한단편화를해소하기위해 Compaction 같은알고리즘을사용한다. 결론적으로 GC 는 Heap 을재활용하기위해 Root Set 에서참조되지않는 Object(Garbage) 제거해가용공간을만드는작업이다. GC 는 Perl, Python, PHP, 닷넷에서도사용되는개념중하나이다. 2. Hotspot JVM Internal 가. Introduction Hotspot JVM 은기본적으로 Generational Collection 방식을사용한다. 즉 Heap 을 Object 의 Generation 별로 Young Area 과 Old Area 로구분하며 Young Area 은다시 Eden Area 과 Survivor Area 으로구분하여사용된다. GC 메커니즘은경험적지식 (Weak Generational Hypothesis 이라고도한다 ) 으로두가지가설을두고있는데첫째로대부분의 Object 는생성된후금방 Garbage 가된다 (high infant mortality). 둘째로 Older Object 가 Younger Object 를참조할일은드물다 라는것이다. 첫번째가설을보면새로할당되는 Object 가모인곳은단편화발생확률이높다고간주된다. Memory 할당은기존 Object 다음주소에서계속수행을하게되며 Garbage 는먼저할당된부분에서많이생길것이다. 이때 Sweep 작업 (Mark 되지않은 Object 를제거 ) 을수행하면단편화가발생하게되며이후 Compaction 처럼비싼작업을해야한다. 때문에 Object 할당만을위한전용공간인 Eden Area 을만들게된거고 GC 당시 Live 한 Object 들을피신시키는 282 2013 기술백서 White Paper
Survivor Area 을따로구성한것이다. 즉 Garbage 가될확률이적은 Object 를따로관리한다 는것이다. Garbage 를추적하는부분은 Tracing 알고리즘을사용한다. 즉 Root Set 에서 Reference 관계를추적하고 Live Object 는 Marking 한다. 이러한 Marking 작업도 Young Generation 에국한되는데 Marking 작업은 Memory Suspend 상황에서수행되기때문이다. 전체 Heap 에대한 Marking 작업은긴 Suspend Time 을가져갈것이기때문이다. 그런데만약이런상황에서 Older Object 가 Young Object 를참조하는상황이있다고가정하면존재여부체크를위해 Old Generation 을모두찾아다닐수있고따라서 Suspend Time 도길어진다. 그렇기때문에 Hotspot JVM 은 Card Table( 이벤트프로그램 ) 이란장치를마련했다. TLAB 이란? [ 그림 2] Thread 들이 TLAB 을사용하여 Memory 에 Object 를할당하는과정 Object 할당은기존에할당된 Memory 번지바로뒤부터하게된다. 이때는 Free List 검색등부가적인작업없이신속하게작업이가능하다. 그러나반드시 Bump-the-pointer 같은기술로동기화작업이수반되어야한다. JVM 은 Multi Thread 기반이므로여러 Thread 가가장최근할당된 Object 뒤공간을동시에요청하면동기화이슈로문제가발생한다. Part 2 APM 283
Hotspot JVM 은 Bump-the-pointer 기술에 Thread Local Allocation Buffer( 이하 TLAB) 기술을추가로사용하는데 TLAB 은 Thread 마다할당주소범위를부여하여그범위내동기화작업없이빠른할당이가능하다 ( 그림 2 는 5 개의 Thread 를표현 ) 만약 TLAB 을사용하지않으면가장먼저요청한 Thread T1 이 Heap lock 을걸로 Allocation 수행하며다른 Thread 들대기하게될것이다. 단 TLAB 을 Thread 에게최초할당할때는동기화이슈가발생한다. Card Table 이란? [ 그림 3] Older Object 가 Young Object 를참조하는경우 Card Table 의활용 Card Table 이란 Old Generation 의 Memory 를대표하는별도 Memory 구조이다 (Old Generation 의일부는 Card Table 로구성되어있다 ). 만약 Young Generation 의 Object 를참조하는 Old Generation 의 Object 가있다면 Old Generation Object 의시작주소에카드 ( 일종의 Flag) 를 Dirty 로표시하고 (Dirty Card) 해당내용을 Card Table 에기록한다. 이후해당 Reference 가해제되면표시한 Dirty Card 도사라지게끔하여 Reference 관계를쉽게파악할수있게했다. 때문에 Hotspot JVM 은이러한장치를통해 Minor GC 수행중 Card Table 의 Dirty Card 만검색하면빠르게 Reference 관계를파악할수있으므로위에서설명한두번째가설을보완했다고할수있다. 참고로 Card 는 Old 의 Memory 512bytes 당 1bytes 의공간을차지한다. 284 2013 기술백서 White Paper
나. Hotspot JVM Heap 구조 [ 그림 4] GC 대상 Area GC 대상 Area 는 Young, Old Generation 과 Permanent Area 인데 Hotspot JVM 은각 Generation 별로각각 GC 를수행한다. 이때 Young Generation 에서발생하는 GC 를 Minor GC 라고한다. Young Generation 은빈번하게 GC 가수행되는영역이며성숙된 Object 는 Old Area 으로 Promotion 된다. 여기서성숙된 Object 란말은 Application 에서특정회수이상참조되어기준 Age 를초과한 Object 를말한다. Promotion 과정중 Old Generation 의 Memory 도충분하지않으면해당 Area 에도 GC 가발생하는데이를가리켜 Full GC(=Major GC) 라고한다. Permanent Area 의 Memory 가부족해도 GC 가발생할수있는데이때는너무많은수의 Class Object 가로딩되어 Free Space 가없어졌기때문이며 Permanent Area 가부족하면 Heap(Young + Old) 에 Free Space 많더라도 Full GC 발생한다. 참고로 Major GC 는 Suspend 시간을더길게가져간다. Part 2 APM 285
다. Hotspot JVM option [ 그림 5] Hotspot JVM Memory Options 옵션 설명 -Client Client Hotspot VM 으로구동한다.(Client Class) -Server Server Hotspot VM 으로구동한다.(Server Class) -Xmn<Size> / -Xmx<Size> Young Generation 의최대 / 최소 Size 설정한다. -XX:NewSize=<Size> Intel CPU 에서는 Default 640kbytes, 그외에 는 2.124Mbytes -XX:MaxNewSize=<Size> 1.4 버전이후 NewRatio 에따라자동계산한다. -XX:MaxPermSize Permanent Area 의최대 Size 설정한다. Default 64Mbytes -XX:SurvivorRatio=<value> 값이 n 이면 n:1:1(eden:survivor1:survivor2) 이다. Default 286 2013 기술백서 White Paper
는 8 값이 n 이면 Young:Old 비율은 1:n -XX:NewRatio=<value> Client Class 는 Default 8 이다. Server Class 는 Default 2 이며 Intel 계열 CPU 를사용하면 Default 12 이다. Minor GC 는 Eden Area 뿐만아니라 Survivor Area 가 Full 되 도발생 Survivor Area 가 Minor GC 를유발하는비율을말하 -XX:TargetSurvivorRatio=<value> 며 Default 50 즉 Survivor Area 가 50% 만차도 Minor GC 발생한다. 높게지정하면 Survivor Area 활용도높아져 Minor GC 발생빈 도낮출수있다. - XX:MinHeapFreeRatio=<percent> 전체 Heap 대비 Free Space 가지정된수치이하면 Heap 을 - Xmx 로지정된수치까지확장한다. Default 40 ( 늘림 ) - XX:MaxHeapFreeRatio=<percent> 전체 Heap 대비 Free Space 가지정수치이상이면 -Xms 까지 축소한다. Default 70 ( 줄임 ) MinHeapFreeRatio 와 MaxHeapFreeRatio 는 -Xms 와 -Xmx 로지정한 Memory 크기와같으면아무런영향이없다. 일반적으로 Heap Size 최대 / 최소값을같게지정하는걸권장하는데 Memory 부족하면다르게설정하기도한다. 왜냐하면 Memory Size 를동적으로늘리고줄이는건성능에많은영향을미치기때문이다. Server Class 기준 Default 값동작방식 1. Default Old Area 크기는 Young Area 크기의두배이다. Survivor Area 크기는 Young Area 크기의 1/10 이다. Part 2 APM 287
Survivor Area 의사용률이 50% 를넘으면 GC 발생한다. Permanent Area Default Max 값은 64Mbytes 이다. 최초 Young Area 크기는약 2M, 이후 NewRatio 값에의해최대값이조정된다. 전체 Heap 에서 Free Size 가 40% 이하면 Heap Size 증가하고 70% 이상이면 Heap Size 감소한다. JVM 의최대, 최소값설정을안하면기본 64MB 를최대 Memory 로지정한다. 3. Hotspot JVM 의 Garbage Collector 가. Introduction 업무요건이복잡해지고시스템이점점거대해지면최근에는자연스럽게 JVM Heap Size 설정이커지게되었다. 그러나그로인해 GC 로인한 Suspend 현상도이슈로대두되게되었다. Hotspot JVM 은기본적으로 Generation 별로다른 Garbage Collection 알고리즘을선택할수있다. 1) Garbage Collector 관련옵션 288 2013 기술백서 White Paper
간단히설명하면기본적으로 Parallel Collector 는모든 Resource 를투입하여 Garbage Collection 를빨리끝내는전략으로대용량 Heap 에적합하다. CMS Collector 는 Suspend Time 을분산시켜채감 Pause Time 줄이고자할때사용된다. Incremental Collector 는 Low Pause Collector 에속하는데현업에서는거의사용안한다. JAVA 7 에서는 Garbage First Collector( 이하 G1 Collector) 를사용할수있는데 (JAVA 6 에서도선택가능 ) Generation 을물리적으로구분하지않고 Region 이라는단위로쪼개서관리를한다. G1 Collector 는거의 Real Time 에가깝게 Suspend Time 을감소시킬수있지만아직안정성이검증되지않아많은사이트에서잘사용되지는않는다. 표에서보다시피각 Collector 마다다양한알고리즘을사용하고있는데최근추세로는결국 Parallel-Concurrent 로수렴되고있다. 참고로 IBM JVM 도역시동일한추세를보이고있다. 나. Serial Collector Young / Old Generation 모두 Serial 로 Single CPU 를사용한다. 즉 1 개의 Thread 를가지고 GC 를수행한다. Client Class 의기본 Collector 이며향후더이상지원하지않을예정이라고한다. 다. Parallel Collector Multi Thread 가동시에 GC 를수행하며적용범위는 Young Area 에국한된다. Old Area 은 Mark-and-Compacting 알고리즘이사용되며 Single Thread 방식이다. Server Class 의 JVM 에서 Default Collector 이며 Client Class 에서도옵션설정으로사용이가능하다. 단 CPU 가 1 개라면해당옵션무시된다. 1) Young Area 의알고리즘 : Parallel Copy [ 그림 6] Copy 알고리즘비교 Part 2 APM 289
Eden, Survivor Area 의 Live Object Copy 작업을여러 Thread 가동시수행 (Suspend 현상발생 ) 한다. 투입한 Resource 만큼 Suspend Time 을단축할수있다. Memory 특성상같은 Memory 공간을두 Thread 가접근하면 Corruption 발생할수있지만 Hotspot JVM 은 PLAB(Parallel Allocation Buffer) 라는 Promotion Buffer 를마련하여이런 Corruption 을회피하고있다. PLAB 이란? GC Thread 가 Promotion 시 Thread 마다 Old Generation 의일정부분을할당 (1024bytes 단위 ) 하고다사용하면다시 Buffer 를재할당한다. 단 Old Area 에단편화가발생할수있는데이는많은 Thread 가자신의버퍼를할당받고사용하지않거나어쩔수없이발생하는버퍼내자투리공간때문이다. TLAB 과 PLAB 2. TLAB 은 Young Area 의 Fast Allocation 을위한것 (Eden Area) PLAB 은 Promotion 과정중동기화문제를회피 (Old Area) TLAB 는 4K 단위로, PLAB 은 1K 단위로할당 290 2013 기술백서 White Paper
옵션 설명 -XX:+UseParallelGC Parallel Collector 사용옵션이다. -X:ParallelGCThreads= 개수 Parallel GC Thread 개수설정한다. Default 는 CPU 개수 설정하면 Eden Area 의 Reachable Object 는바로 -XX:+AlwaysTenure Old Area 으로 Promotion 된다. Parallel Collector 사용시에만유효하다. -XX:MaxTenuringThreashOld=0 과같음 (age 를 0 으로해서바로바로승격시키겠다는의미 ) Survivor Area 가 Full 되는경우를제외하고 Object -XX:+NeverTenure 를 Promotion 안되게설정하는옵션이다. Parallel Collector 사용시에만유효하다. (age 자체를없애서승격이안되게한다.) -XX:MaxGCPauseMillis= 값 설정값이하로 GC 의 Pause Time 을유지하라는설 정이다. Application 수행시간대비전체 GC 의시간비율을 -XX:GCTimeRatio= 값 말한다. 9 로설정하면 1/(1+19) = 5% Default 는 99(1% 의 GC Time Ratio 를의미 ) -XX:+UseAdaptiveSizePolicy GC 횟수, Generation 의각 Area 비율, free Heap Size 등통계정보를바탕으로 Young, Old Generation 의크기를자동설정하는옵션이다. Part 2 APM 291
-XX:YoungGenerationSizeIncrement= 값 Young Generation 의확장비율설정옵션이다. Default 20(20% 씩증가 ) Heap 의 Growing Percent 대비 Shrink 를수행할 -XX:AdaptiveSizeDecrementScaleFactor= 값 Ratio 의미 값이 4 이고 Heap growing percent 가 20 이면 20/4 = 5 % 가된다. Default 는 4 이므로 Default shrink Ratio 는 5% GC 로확보해야하는최소 Free Space 설정한다. -XX:GCHeapFreeLimit= 값 값은최대 Heap Size 에대한비율을의미한다. Default 는 5(%) OOME 방지에도움이되는옵션이다. -XX:MaxHeapFreeRatio=<percent> 전체 Heap 대비 Free Space 가지정수치이상이면 -Xms 까지축소하는옵션이다. Default 70 ( 줄임 ) 2) Parallel Collector 의옵션 Default 값동작방식 3. Application 수행시간대비 GC 수행시간은 Default 1% 다. Application 수행시간의 90% 못넘는다. Young Area 은확장할때 20% 씩증가하고 5% 씩감소한다. -XX:+UseAdaptiveSizePolicy 를쓰면 Heap 크기가자동설정된다. GC 를했으면반드시최대 Heap Size 대비 5% 의 free 공간확보해야한다. 라. CMS Collector CMS Collector 는 Suspend Time 을분산하여응답시간을개선한다. 비교적자원이여유있는 상태에서 GC 의 Pause Time 을줄이는목적이며 Size 가큰 Long Lived Object 가있는경우 292 2013 기술백서 White Paper
에가장적합하다. Young Area 에는 Parallel Copy 알고리즘, Old Area 에는 Concurrent Mark-Sweep 알고리즘이사용된다. 1) Old Area 의 Concurrent Mark-Sweep 알고리즘 [ 그림 7] CMS Collector 의 Old Area 단계별동작방식 - Initial Mark : Single Thread 만사용한다. Application 이중지되고 Application 에서직접 Reference(Root set 에서한단계의 Reference 관계 ) 되는 Live Object 만구별한다. Suspend 상태지만빠르다. - Concurrent Mark : Single Thread 만사용한다. Application 은수행되고 GC Thread 외 Working Thread 는 Application 수행이가능하다. Initial Mark phase 에서선별된 Live Object 가 Reference 하고있는 Object 를추적해 Live 여부구별한다. - Remark : Multi Thread 가사용되며 Application 중지된다. 이미 Marking 된 Object 를다 시추적, Live 여부확정, 모든 Resource 를투입한다. Part 2 APM 293
- Concurrent Sweep : Single Thread 만사용한다. Application 은수행되고최종 Live 로판명된 Object 제외한 Dead Object 를지운다. 단 Sweep 작업만하고 Compaction 작업수행안한다. 항상 Compaction 작업은 Heap 의 Suspend 를전제로하는데반복된 Sweep 은단편화를유발한다. 때문에 Free List 를사용하여단편화를줄이는노력을한다. [ 그림 8] Heap 의단편화모습 Free List 승격 (Promotion) 할당을할때 Young Area 에서승격된 Object 와크기가비슷한 Old Area 의 Free Space 를 Free List 에서탐색하게된다. 또한승격되는 Object Size 를계속통계화하여 Free Memory 블록들을붙이거나쪼개서적절한 Size 의 Free Memory Chunk 에 Object 할당한다. 그러나이러한작업은 GC 수행중 Young Area 에부담을주게되는데그이유는 Free List 에서적절한 Chunk 크기를찾아 Allocation 해야되기때문이며시간도오래걸린다. 즉이말은곧 Eden/Survivor Area 에서의체류시간이길어진다는의미이다. Compaction 작업을수행하면 Old Area 에올라온 Object 를그냥순서대로할당하여 Fast Allocation 이가능한데 Compaction 이너무고비용이라손익을따져봐야한다. Promotion 이빈번하지않다면성능이득이있다. 294 2013 기술백서 White Paper
2) CMS Collector 의 Floating Garbage 문제 : Old Area [ 그림 9] CMS Collector 의 Old Area 동작방식 CMS Collector 는단편화외 Floating Garbage(Garbage 면서수거되지않고붕뜬 Garbage) 문제가있다. 위그림을설명하면다음과같다. a, b, c 는 Reachable Object 로판명, d 는 Dead Object 이다. a, b, c 가참조하는 1, 2, 3 를각각추적하여참조관계를알게된다. 이단계는 Application Thread 도같이일을하는 Concurrent 단계이다. 기존 Reachable Object 가 Root set 을잃고 Dead Object 가될수있다. 또 e, f, 5, 6 이 Promotion 되서 Old Area 에등장한다. 그러나 CMS 에서는 1 단계에서 Live Object 로인정된 Object 만 GC 대상이다. 만약여기서 e, 5 가승격되자마자작업종료되면 Concurrent Mark 단계가끝나기전에 Dead Object 가된다. 이를 Float Garbage 라고한다. Part 2 APM 295
f, 6 은 Old Area 에계속남아있다. Float Garbage 는다음번 GC 에서사라지며 f, 6 도다음 GC 의 Initial Mark 대상이다. Float Garbage 는 GC 완료시점까지 Garbage 가완벽히사라지지않음을말하는데이는잠재적으로 Old Area 확장시키게되는요인이다. 또한 CMS Collector 라고하더라도 Suspend Time 은완벽히못없앤다. Young Area 은아직 Suspend Time 을가정, Young Area 의 GC 와 CMS 의 Remark phase 연달아수행되면의도한 Suspend Time 보다길어질것이다. 그래서 CMS 는 GC 에서 Schedule 을고려한다. CMS Collector 의 Scheduling 4. GC 시간과 Old Area 가 Full 되기까지남은시간같은정보등을계속수집한다. Remark phase 가 Minor GC 중간지점에오도록조정한다. Initial Mark phase 는빨라서 Minor GC 와겹쳐도무시할만하다. 만약 Old Area 가 Full 된상태에 GC 를수행하면 Concurrent 단계에서 OOME 발생가능크다. 때문에 Old Area 가 Full 에근접하는시점과 GC 발생주기가비슷해지면 GC 를시작한다. 그외에도 Old Area 점유율을지정해해당값이넘으면 GC 를수행한다.(Default 는 68%) 이값이작으면 GC 를더자주수행한다. 결론적으로 CMS Collector 는 Old Area 에 Object 할당할때 Free list 를사용해단편화를최소화하고 Scheduling 으로 Remark 단계가 Minor GC 중간지점에오도록조정하여 OOME 를방지한다. 3) CMS Collector 옵션 옵션 설명 -XX:+UseConcMarkSweepGC CMS Collector 를사용한다. -XX:+UseParNewGC Young Area 의 GC 를 Parallel 로수행한다. Old Area 가 CMS 를사용할때만의미있다. -XX:+CMSParallelRemarkEnabled Remark 를병렬로수행한다. 296 2013 기술백서 White Paper
-XX:CMSInitiatingOccupancyFraction= 값 Old Area 점유율을지정한다. 1~100 까지가능, 이값넘으면 GC 시작, Default 68 -XX:CMSExpAvgFactor= 값 CMS 통계를위한지수평균낼때가중치, 1~100, Default 25 -XX:+UseCMSInitiatingOccupancyOnly CMSInitatingOccupancyFraction 옵션에따른 GC 만수 행하도록지정한다. 4) Incremental Mode of CMS Collector [ 그림 10] 2 Core 의 CMS Collector 동작방식 Part 2 APM 297
CMS Collector 는 Pause Time Goal 가지는데기본적으로 GC 단계를세분화해 Concurrent 한진행을도모한다. Concurrent 작업이큰실효가없으면 GC 의 Pause Time 줄이는효과나타나지않는다. GC 전과정동안 1 개의 CPU 가 GC Thread 에의해내내점유되는데이러면 Concurrent 작업은나머지 1 개 CPU 로수행하게되므로 Concurrent 의의미가퇴색되게된다. 그래서 CMS Collector 는별도 Incremental 모드지원하는데이는보다정교한 Scheduling 을한다. Concurrent phase 를작은시간단위로쪼개서 Minor GC 와겹치지않게한다. 또 Duty cycle 을둬한개의 CPU 를점유하는시간제한을둬서 GC 의일량을조절한다. Incremental CMS Collector 는기본 Duty cycle 을자동계산한다 ( 수동으로설정가능 ) 5) Incremental mode's options 옵션 설명 -XX:+CMSIncrementalMode CMS Collector 을선택한상태에서사용가능하다. Default false 이며설정하면 -XX:CMSInitialingOccupancyFraction 옵션은무시된다. -XX:+CMSIncrementalPacing Duty 사이클자동설정을한다. Default false Duty cycle 을수동으로조정한다. 값은연속된 Minor GC 사이의시간 -XX:CMSIncrementalDutyCycl e= 값 비율이다. Default 50(Minor GC 끝나고다음 Minor GC 시작할때의시간의 1/2(50%) 지점지나는시점 ) 1~100, -XX:+CMSIncrementalPacing 사용하면자동설정초기값은 Default 인 50 으로설정된다. -XX:CMSIncrementalDutyCycl emin= 값 Duty cycle 을자동설정으로할때 Duty cycle 의하한선설정한다. Default 10 298 2013 기술백서 White Paper
Free Space 의가중치, 값커지면 Old Area 의 Free Space 는실제보 -XX:CMSIncrementalSafetyFa ctor= 값 다작게산출, 작게할수록실제 Free Space 와동일수준설정한다. De fault 10 CMS_free_dbl = CMS_free_dbl*(100.0 - CMSIncrementalSafety Factor)/100.0 -XX:CMSIncrementalOffset= 값 Duty cycle 을두 Minor GC 사이의오른쪽인새로시작하는 Minor GC 쪽으로이동시키는값을지정한다. Default 0 마. Parallel Compaction Collector Parallel Collector 에서 Old Area 에새로운알고리즘 (Mark and compact -> Parallel compacting) 이추가된개념으로 Multi CPU 에서유리하다. Old Area 의 Collection 시간감소시켜효율증가하나몇몇 Application 이 Large system 을공유해 CPU 를확실히점유못하면오히려제성능발휘하지못한다. 이경우 Collection Thread 개수를줄여서사용한다. 1) Parallel Compaction 알고리즘 : Old Generation Part 2 APM 299
[ 그림 11] Parallel Collector 의 Old Generation 동작방식 - Mark phase : [ 그림 12] Parallel Compaction Collector 의 Mark phase 단계동작방식 Reachable Object 를체크하마 Parallel 작업으로수행된다. Old Area 의 Region( 논리적구 역, 2kbytes 정도의 chunk) 이라는단위로균등하게나눈다. Region 구분되면 Collection 300 2013 기술백서 White Paper
Thread 들은각각 Region 별로 Live Object 를 Marking 한다. 이때 Live Object 의 Size, 위치 정보등 Region 정보가갱신된다. 이정보들은각 Region 별통계를낼때사용한다. - Summary phase : Mark phase 로 Compaction 의일량을산정한다. [ 그림 13] Parallel Compaction Collector 의 Dense Prefix 설정모습 하나의 Thread 가 GC 를수행, 나머지는 Application 을수행, Summary 단계가 Mark 단계결과를대상으로작업을수행한다. Region 단위이며 GC Thread 는 Region 의통계정보로각 Region 의 Density 평가한다. Density 는각 Region 마다 Reachable Object 의밀도를나타내는데 Density 를바탕으로 Dense prefix 를설정하게된다. Dense prefix 는 Reachable Object 의대부분을차지한다고판단되는 Region 이어디까지인가구분하는선이며더불어다음단계의대상을구분해준다. Dense premix 왼편 (Memory 번지작은쪽 ) 에있는 Region 은이후 GC 의대상에서제외, 나머지만 Compaction 이수행된다. Hotspot JVM 에서 Compaction 은보통 Sliding Compaction 을의미하는데이는 Live Object 를한쪽방향으로이동시킨다. 오랜기간참조된 Object 는더오래 Heap 에머무를가능성이큰데이를전제로어느지점까지의 Object 는거의 Garbage 되지않을확률이높고그게왼쪽으로갈수록높아진다. 즉 Parallel Compaction Collector 는 Region 별 Density 를평가하고 GC 를수행할범위를정하는 (Dense prefix) 작업을해 Compaction 의범위줄여결과적으로 GC 소요시간줄인다. Dense prefix 설 Part 2 APM 301
정작업이끝나면 Compaction 의대상이되는 Region 의 First Live Object 주소를찾아저장 작업을수행한다. - Compaction phase : Summary 된데이터를기반으로 Compaction 수행한다. [ 그림 14] Parallel Compaction Collector 의 Compaction phase 동작방식 Heap 을잠시 Suspend 상태로만들고 Thread 들이각 Region 을할당받아 Compaction 을수행한다. Compaction 작업은 Garbage Object 를 Sweep 하고 Reachable Object 를왼편으로몰아넣는것이다. 작업은 Destination Region, Source Region 각각구별하여작업을수행한다. 위그림에서 Dense prefix 이후 Region 들이 Destination 과 Source 로구분한다. ( 마지막 Region 은모두 Garbage Object 로만되어서별도구분하지않은것이다.) Region 마다배정된 Thread 가 Garbage Object 를 Sweep 한다. Thread1 은 Destination Region 의 Garbage Object 를 Sweep, Thread2 는마지막 Region 을 Sweep 한다. Source Region 외 Region 에는 Garbage 사라지며 Destination Region 에는 Live Object 만남게되고 Thread1 302 2013 기술백서 White Paper
이 Source Region 의 Garbage 들을수거한다. 마지막으로 Source Region 에남겨진 Live Object 는 Destination Region 으로이동한다. 2) Parallel Compaction Collector's 옵션 옵션 설명 -XX:+UseParallelOldGC 활성화옵션이다. -XX:+UseParallelOldGCCompa cting Parallel Compaction Collector 사용시설정한다. Parallel Compaction 사용여부에해당한다. Default true -XX:+UseParallelDensePrefixU pdate Summary phase 에서 Dense prefix 를매번갱신할지에대한설정한 다. Default true 바. Garbage First Collector 앞으로는 G1 Collector 가 CMS Collector 를대체할전망이다. CMS Collector 에비해 Pause Time 이개선되었고예측가능한게장점이다. Young Area 에집중하면효율이좋으나 CMS 처럼 Old Area 의단편화가있으며 Freelist 사용의문제점과 Suspend Time 가길어지는현상등이있다. G1 은물리적 Generation 구분을없애고전체 Heap 을 1Mbytes 단위 Region 으로재편한다. Parallel Compaction Collector 의 Region 단위작업과 Incremental 의 Train 알고리즘을섞어놓은느낌이다. Mark 단계에서최소한의 Suspend 시간으로 Live Object 골라내는건 Parallel Compaction Collector 와비슷하다. Region 별로순차적인작업이진행되고 Remember set 을이용한다. Garbage First 라는의미는 Garbage 로만꽉찬 Region 부터 Collection 을시작한다는의미로발견되자마자즉각 Collection 을한다. Garbage Object 가대부분인 Region 의경우 Live Object 는 Old Region 에서다른 Old Region 으로 Compaction 이이루어진다. G1Collector 에서 Young, Old Area 은물리적개념이아니고 Object 가 Allocation 되는 Region 의집합을 Young Generation, Promotion 되는 Region 의집합을 Old Generation 이라고한다. Part 2 APM 303
G1 Collector 의기본적인 GC 메커니즘 5. 전체 Heap 을큰네모로표현했고, 작은네모가 Region 을의미한다. 음영이들어간작은네모는 Old Generation 의 Region, 음영이들어가지않은네모는 Young Generation 의 Region 을의미한다. 3 표시는 Young Generation 에서방금 Copy 된 Survivor Region 이다. 4 표시는방금 Promotion 되어새로 Old Generation 이된 Region 이다. Minor GC 가발생하면 Young Area 의 Region 들을대상으로 Reachable Object 를찾고 A ge 가되지않은 Object 는 Survivor Region 으로 Copy 한다. Promotion 의대상 Object 는 Old Generation 으로 Copy 한다. 기존 Young Generation Region 은 Garbage 로간주해 Region 단위로할당을해지한다. Young Area GC 끝나면바로 Old Area GC 시작하는데단 Heap 전체에대한 GC 는아니며철저히 Region 단위이다. GC 로인한 Suspend 현상도해당 Region 을사용하는 Thread 에국한된다. G1 Collector 가 Region 내에 Reference 를관리하는방법은 Remember set 이용한다. 전체 Heap 의 5% 미만공간을각 Region 의참조정보를저장하는 Remember set 으로할당한다. Remember set 은 Region 외부에서들어오는참조정보를가지고있다. 이로인해 Marking 작업시 trace 일량줄여줘 GC 효율을높이게된다. 1) Garbage First Collector 의 Garbage First Collection G1 Collector 의 Garbage Collection 은 4 단계, 세부적으로는 6 단계이다. 304 2013 기술백서 White Paper
[ 그림 15] G1 Collector 의단계별동작방식 기본적으로 Allocation 때 Memory 압박이생기거나임계값이초과될때마다 GC 발생한다. 2) Young GC GC 는 Young Area 에서부터시작하며 Minor GC 와동일한개념이다. Suspend Time 이존재하며 Multi Thread 가작업한다. Live Object 는 Age 에맞게 Survivor Region, Old Region 으로 Copy 되며기존공간은해지된다. 이후새로운 Object 가할당되는 Young Region 은 Survivor Region 과그근처비어있는 Region 이된다. 3) Concurrent Mark phase (Mark -> Remark) : Old Area GC 시작 Part 2 APM 305
[ 그림 16] G1 Collector 의 Concurrent Mark phase 이후모습 - Marking 단계 : Single Thread, 전체적으로 Concurrent, 이전단계때변경된정보바탕으 로 Initial Mark 빠르게수행한다. - Remarking 단계 : Suspend 있고전체 Thread 가동시작업, 각 Region 마다 Reachable Object 의 Density 를계산, 그후 Garbage Region 은다음단계로안넘어가고바로해지된다. 여기서는 CMS 보다빠르게진행한다. Concurrent Mark phase 에서는 snapshot-at-the-beginning(satb) Marking 알고리즘사용한다. 이는 GC 를시작할당시 Reference 를기준으로모든 Live Object 의 Reference 를추적하는방식이다. 단 Mark 작업은 Concurrent phase 이므로 Reference 가계속변경된다. G1 Collector 는위작업을위해 write barrier 를이용, 각 Reference 의생성 / 분리를기록한다. 이기록은 GC 시작시만들어진 snapshot 과비교되어 Marking 작업을빠르게수행한다. 4) Old Region reclaim phase (Remark -> Evacuation) 306 2013 기술백서 White Paper
[ 그림 17] G1 Collector 의 Old Region reclaim phase 이후모습 - Remark 단계 : Concurrent 작업, Multi-Thread 방식, GC 를위해 Live Object 의비율이낮 은몇개의 Region 골라낸다. - Evacuation Pause 단계 : 독특하게 Young Area 의 GC 를포함, 앞의 Remark 단계에서골라낸 Old Region 은 Young Region 과같은식으로 Evacuation 한다. 원표시의 Region 들이 Evacuation 의대상이며하얀빗금이 Old Region, 나머지는 Young Region 이다. Young Region 은 GC 의첫단계인 Young GC(Evacuation) phase 의결과로생성된 Survivor Region 과그근방의 empty Region 들에 Object 가 Allocation 되생긴 Region 인데여기에 Remark 에서선택된 Old Region 들까지 Evacuation 단계에서같이 Collection 된것이다. 결과로좌측상단으로 Survivor Region 과 Old Region 이하나생성된다. Old Region reclaim phase 가끝난후 Heap 에몇개의 Garbage Object 만존재하는, Live Object 의 Density 가비교적높은 Region 들만남게된다. 이들도언젠간 GC 될것이다. 5) Compaction phase 다른 Compaction 과달리 Concurrent 작업을수행한다. Region 단위로작업을수행하니까가 능한일이다. Compaction 의주목적은 Free Space 를병합해단편화방지하는것이다. 많은 수의 Region 을균등하게조금씩사용하게되는부작용을방지하는것. 6) Garbage First Collector's option Part 2 APM 307
옵션 설명 -XX:+UseG1GC 활성화옵션이다. -XX:+UnlockExperimentalVMOptions JAVA 1.6 에서는해당옵션을같이사용해주어야한다. 4. GC 튜닝 가. " 모든 Java 기반의서비스에서 GC 튜닝을해야할까?" -Xms 옵션과 Xmx 옵션으로 Memory 크기를지정했다. -Server 옵션이포함되어있다. 시스템에 Timeout 로그와같은로그가남지않는다. 위와같은경우라면기본적인설정도되어있지않으므로 GC 옵션을통한조정이필요한상황이라고할수있다. 단 GC 튜닝과는별개로 GC 튜닝을하는이유가무엇인지근본적인원인을생각해보자. Java 에서생성된 Object 는 Garbage Collector(Garbage Collector) 가처리해서지운다. 생성된 Object 가많으면많을수록 Garbage Collector 가처리해야하는대상도많아지고, GC 를수행하는횟수도증가한다. 즉운영시스템이 GC 를적게하도록하려면 Object 생성을줄이는작업이동반되어야한다 예를들면첫째로 String 대신 StringBuilder 나 StringBuffer 를사용해야한다. 문자열을변경할경우 String 은 Object 자체를복사해서값을변경하므로 Heap 에 Object 가계속증가하는반면 StringBuilder 나 StringBuffer 는내부적으로 Object 복사가이뤄지지않고단지 Object 가가지고있는값만변경된다. 둘째로로그를최대한적게쌓도록하는것이좋다. 하지만어쩔수없는현실도있다. 대용량의 XML 파일 Parsing 은 Memory 를가장많이사용한다. 아무리 String 을최대한사용안하고 Log 처리를잘하더라도, 10~100 MB 짜리 XML 파일을 Parsing 하면엄청난임시 Memory 를사용한다. 그렇다고 XML 을사용하지않기는어렵다. 308 2013 기술백서 White Paper
나. GC 튜닝의목적 GC 튜닝의목적은궁극적으로 System 의 Suspend Time 감소에있으며세부적으로나눠보면첫째로 Old Area 으로넘어가는 Object 의수를최소화하는것이며둘째로 Full GC 의실행시간을줄이는것이다. 다. Old Area으로넘어가는 Object의수최소화의중요성 JDK 7 부터본격적으로사용할수있는 G1 Collector 를제외하고 Hotspot JVM 에서제공하는모든 GC 는 Generational GC 이다. 즉 Eden Area 에서 Object 가처음만들어지고 Survivor Area 을오가다가끝까지남아있는 Object 는 Old Area 으로이동한다. 간혹 Eden Area 에서만들어지다가크기가커져서 Old Area 으로바로넘어가는 Object 도있긴하다. Old Area 의 GC 는 New Area 의 GC 에비하여상대적으로시간이오래소요되기때문에 Old Area 으로이동하는 Object 의수를줄이면 Full GC 가발생하는빈도를많이줄일수있다. New Area 의크기를잘조절함으로써큰효과를볼수는있다. 라. Full GC 시간줄이기 Full GC 의실행시간은상대적으로 Minor GC 에비하여길다. 그래서 Full GC 실행에시간이오래소요되면 ( 통상 1 초이상이면오래걸렸다고본다.) 연계된여러부분에서타임아웃이발생할수있다. 그렇다고 Full GC 실행시간을줄이기위해서 Old Area 의크기를줄이면자칫 Out Of Memory Exception 이발생하거나 Full GC 횟수가늘어난다. 반대로 Old Area 의크기를늘리면 Full GC 횟수는줄어들지만실행시간이늘어난다. Old Area 의크기를적절하게설정해야한다. 마. GC의성능을결정하는옵션기본적으로 -Xms 옵션, -Xmx 옵션, -XX:NewRatio 옵션을사용해야한다. 특히 -Xms 옵션과 -Xmx 옵션은필수로지정해야하는옵션이다. 그리고 NewRatio 옵션을어떻게설정하느냐에따라서 Permanent Area 의크기가조정되고따라서 GC 성능에도많은차이가발생한다. Perm Part 2 APM 309
Area 의크기는 OutOfMemoryException 이발생하고, 그문제의원인이 Perm Area 의크기 때문일때에만 -XX:PermSize 옵션과 -XX:MaxPermSize 옵션으로지정해도큰문제는없다. 다음으로 Collector 를결정해야한다. 바. GC 튜닝의절차 1) GC 상황모니터링 가장쉽게 GC 상황을모니터링하는방법은 jstat 명령어를활용하는방법이다. 해당명령을이용해 Append 로파일에로그내역을쌓게하여추이를관찰할수있다. 기본적으로가장많이사용하는방법은 verbosegc 옵션과 -Xloggc:< 파일위치 > 옵션을사용하여 JVM 에서로그를떨구도록설정하는방법이다. 본문서에서는 InterMax 를활용하여 GC 추이를관찰하고자한다. [ 그림 18] InterMax 에서 GC 모니터링 2) 모니터링결과분석후 GC 튜닝여부결정 분석한결과를확인했는데 GC 수행에소요된시간이 0.1~0.3 초밖에안된다면굳이 GC 튜닝이필요없을수있다. 하지만 GC 수행시간이 1~3 초, 심지어 10 초가넘는상황이라면 GC 튜닝을진행해야한다. 그런데만약 Java 의 Memory 를 10GB 정도로할당해서사용하고있다면 GC 튜닝전에시스템의 Memory 를왜높게잡아야하는지에생각해봐야만한다. 만약 Memory 를 1GB 나 2GB 로지정했을때 OutOfMemoryException 이발생한다면 Heap 덤프를떠서그원인을확인하고문제점을제거해야만한다. 310 2013 기술백서 White Paper
3) GC 방식지정및결과분석 GC 옵션을지정하고적어도 24 시간이상데이터를수집한후에분석을실시한다. 로그를분석 해 Memory 가어떻게할당되는지확인하며 GC 방식 /Memory 크기를변경해가면서최적의옵 션을찾아나간다. 사. 일반적으로 GC 튜닝이필요없는수치 Minor GC 의처리시간이 50ms 내외 Minor GC 주기가 10 초내외 Full GC 의처리시간이보통 1 초이내 Full GC 주기가 10 분에 1 회 절대값은아니며서비스상황에따라다르다. Full GC 처리속도가 0.9 초가나와도만족하는서비스가있고, 그렇지않은서비스도있다. 따라서, 이와같은값을확인하고서비스의특성에따라 GC 튜닝작업을진행할지결정한다. 주의할점은 Minor GC 와 Full GC 의시간만보면안된다. GC 가수행되는횟수도확인해야한다. 만약 New Area 의크기가너무작게잡혀있다면 Minor GC 가발생하는빈도도매우높을뿐만아니라 (1 초에한번이상인경우도있음 ) Old Area 으로넘어가는 Object 의개수도증가하게되어 Full GC 횟수도증가한다. 아. GC 방식지정 GC 방식은 Hotspot JVM 을기준으로총 5 가지가있다. 이중에서어떤방식을선택해야한다는원칙은없지만가장좋은방법은 3 가지를다적용해보는것이다. 하지만, 한가지확실한것은 CMS GC 가다른 Parallel GC 보다빠르다는것이다. 그렇다면그냥 CMS GC 만적용하면되겠지만 CMS GC 가항상빠른것은아니다. 일반적인 CMS GC 의 Full GC 는빠르지만 Concurrent mode failure 가발생하면다른 Parallel GC 보다느리다. Parallel GC 와 CMS GC 의가장큰차이점은 Compaction 작업여부이다. Compaction 작업은 Memory 할당공간사이에사용하지않는빈공간이없도록옮겨서 Memory 단편화를제거하는작업이다. Parallel Part 2 APM 311
GC 방식에서는 Full GC 가수행될때마다 Compaction 작업을진행하기때문에시간이많이소요된다. 하지만, Full GC 가수행된이후에는 Memory 를연속적으로지정할수있어 Memory 를더빠르게할당할수있다. 반대로 CMS GC 는 Compaction 작업을기본으로수행하지않는다. Compaction 작업을수행하지않기때문에당연히속도가빠르다. 하지만, Compaction 작업을수행하지않으면디스크조각모음을실행하기전의상태처럼 Memory 에빈공간이여기저기생긴다. 그렇기때문에크기가큰 Object 가들어갈수있는공간이없을수있다. 예를들어 Old Area 에남아있는크기가 300MB 인데도 10MB 짜리 Object 가연속적으로들어갈공간이없을수도있다. 그럴때 Concurrent mode failure 라는경고가발생하면서 Compaction 작업을수행한다. 그런데, CMS GC 를사용할때에는 Compaction 시간이다른 Parallel GC 보다더오래소요된다. 그래서오히려더문제가될수있다. 결론적으로운영중인시스템에가장적합한 GC 방식을찾아내야한다. ( 위문제로인해 CMS 에서다시 Parallel Collector 로다시회귀하는추세 ) 결론적으로, 운영중인시스템특성에따라적합한 GC 방식이다르므로해당시스템에가장적합한방식을찾아야한다. 자. JVM Memory 크기와 GC 의상관관계 Memory 크기가크면 GC 발생횟수는줄어들고 GC 수행시간은증가한다. Memory 크기가작으면 GC 수행시간은줄어들고 GC 발생횟수는증가한다. Memory 크기를크게설정할것인지, 작게설정할것인지에대한정답은없다. 서버자원이좋은시스템이라 Memory 를 10GB 로설정해도 Full GC 가 1 초이내에끝난다면 10 GB 로지정해도된다. 하지만, 대부분의서버는그렇지못하다. Memory 를 10GB 정도로설정하면 Full GC 시간이 10~30 초정도소요된다. 물론이시간은 Object 의크기가어떻게되어있느냐에따라서달라진다. 보통은 GC 튜닝이전에현재상황을모니터링한결과를바탕으로 Full GC 가발생한이후에남아있는 Memory 의크기를봐야한다. 만약 Full GC 후에남아있는 Memory 가 300MB 정도라면 300MB( 기본사용 ) + 500MB(Old Area 용최소 ) + 200 MB( 여유 Memory) 를감안하여 1GB 정도로지정하는것이좋다. 즉, Old Area 을위해서 500MB 이상여유가있는공간을지정해야한다. Memory 크기를지정할때지정해야하는것이한가지더있다. 바로 NewRatio 다. NewRatio 는 New Area 과 Old Area 의비율이다. 312 2013 기술백서 White Paper
XX:NewRatio=1 로지정하면 New Area:Old Area 이 1:1 이된다. 만약 1GB 라면 New Area:Old Area 은 500MB:500MB 가된다. NewRatio 가 2 이면 New Area:Old Area 이 1:2 가된다. 즉, 값이커지면커질수록 Old Area 의크기가커지고 New Area 의크기가작아진다. NewRatio 값은 GC 의전반적인성능에많은영향을준다. New Area 의크기가작으면 Old Area 으로넘어가는 Memory 의양이많아져서 Full GC 도잦아지고시간도오래걸린다. NewRatio 의값이 2 나 3 일때의전반적인 GC 상황이좋을수있다. 5. GC 성능테스트 가. Introduction GC 옵션별로성능테스트를진행하고자한다. 먼저테스트할환경정보는다음과같다. Test Machine 은 Linux 4Core 이고 WAS 는 WebLogic 11g 를사용했으며 Test Source 는아래와같다. Test Case 는총 4 개로 Serial Collector, Parallel Collector, CMS Collector, G1 Collector 를사용하여 GC 수행정보및 TPS 를비교하였다. 기본적으로 GC 정보를 Logging 하기위해 -verbosegc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps - XX:+PrintHeapAtGC -XX:+PrintGCDateStamps 등의옵션을사용했으며 HPJmeter 및 InterMax 를이용해테스트결과를분석및정리하였다. 그리고 WAS 에트랜잭션을발생시키기위해 JMeter Tool 을사용했음을밝힌다. 테스트에사용된 JSP <%@ page contenttype="text/html;charset=euc-kr"%> <%@ page import="java.util.*" %> <html> <head> </head> <body> <h3> <% ArrayList arr1 = new ArrayList(); for(int i=0; i<1200000; i=i+1) { Part 2 APM 313
arr1.add("saldfjlwjefklwjlefjwljflwjklfjlklefkewljwlksdgsdbgsdgbdf"); } Thread.sleep(1000); %> </h3> </body> </html> 나. Case 1 1) Java Options -client -Xms512m -Xmx512m -XX:PermSize=48m -XX:MaxPermSize=128m 2) 결과 GC 종류 GC 수행회수총 GC 수행시간평균 GC 수행시간 TPS Minor GC 1,187 77,000ms 65ms Full GC 128 73,000ms 570ms 4,669 JMeter 에서 User 수를 30 으로설정하고 Ramp-up 없이동시에 10 분동안트랜잭션을날린결과 다. Case 2 1) Java Options -XX:+UseParallelGC (-server 옵션과동일 ) -Xms512m -Xmx512m -XX:PermSize=48m -XX:MaxPermSize=128m 314 2013 기술백서 White Paper
2) 결과 GC 종류 GC 수행회수총 GC 수행시간평균 GC 수행시간 TPS Minor GC 1,300 46,000ms 35ms Full GC 5 1,000ms 200ms 5,809 JMeter 에서 User 수를 30 으로설정하고 Ramp-up 없이동시에 10 분동안트랜잭션을날린결과 Full GC 수행빈도가낮아좀더부하를주기위해아래와같이다시테스트를진행하였다. GC 종류 GC 수행회수총 GC 수행시간평균 GC 수행시간 TPS Minor GC 2,516 241,000ms 96ms Full GC 463 184,000ms 397ms 4,099 JMeter 에서 User 수를 60 으로설정하고 Ramp-up 없이동시에 10 분동안트랜잭션을날린결과 라. Case 3 1) Java Options -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+CMSParallelRemarkEnabled -Xms512m -Xmx512m -XX:PermSize=48m -XX:MaxPermSize=128m 2) 결과 Part 2 APM 315
GC 종류 GC 수행회수총 GC 수행시간평균 GC 수행시간 TPS Minor GC 2,087 134,000ms 64ms Full GC 445 324,000ms 728ms 3084 JMeter 에서 User 수를 60 으로설정하고 Ramp-up 없이동시에 10 분동안트랜잭션을날린결과 마. Case 4 1) Java Options -XX:+UnlockExperimentalVMOptions -XX:+UseG1GC -Xms512m -Xmx512m -XX:PermSize=48m -XX:MaxPermSize=128m 2) 결과 GC 종류 GC 수행회수총 GC 수행시간평균 GC 수행시간 TPS Minor GC Full GC Heap 이 Generation 으로구성되지않으므로해당수치는미표기 2,779 JMeter 에서 User 수를 60 으로설정하고 Ramp-up 없이동시에 10 분동안트랜잭션을날린결과 바. 결론 Case 1 의경우 -client 옵션에의해 Serial GC Collector 가사용되었다. Serial GC Collector 는 GC 를 Single Thread 로진행하기때문에다른 GC Collector 에비해빠르게 GC 를수행하지못한다. 아래그래프를확인해보면부하테스트기간동안계속 Minor 및 Full GC 가계속수행된걸확인할수있다. 316 2013 기술백서 White Paper
[ 그림 19] InterMax 에서확인한 GC 추이 Case2 의경우 Parallel Collector 가선택됐으므로 Young Generation 에대한 Minor GC 는 Multi Thread 가 GC 를수행한다. 때문에 Serial GC Collector 와비교해보면 Minor GC 수행횟수가 1,187 에서 1,300 으로증가하였지만오히려평균 GC Time 은 65ms 에서 35ms 로약두배가량빨라진걸확인할수있다. 즉해당테스트 Machine 의 Core 수만큼 Multi Thread 가 Minor GC 작업을수행하여 Suspend Time 이감소한것이다. 더욱눈에띄는점은 Full GC 횟수가 128 에서 5 로감소한점이다. 이는 Young Generation 의 Object 가 Old Generation 으로 Promotion 되기전에 Minor GC 에의해대부분의 Object 가 GC 되었다는걸의미한다. 결과적으로감소한 Suspend Time 으로인해테스트기간동안좀더많은 Transaction 을처리할수있게되었고 TPS 도 4,669 에서 5,809 으로증가한걸확인할수있다. 이는곧 GC 로인한 WAS 의 Suspend 현상이 TPS 에도많은영향을준다는걸의미한다. 참고로?server 옵션을사용해도 Parallel Collector 가사용된다. 단 Server Class 는 2 개이상 CPU, 2G 이상물리적 Memory, 32bit Windows 를제외한시스템에서만옵션이적용되며그렇지않은경우해당옵션은무시된다. Server Class 가되면컴파일러는 Server Runtime Compiler 를사용한다. 다음으로 Case2 에서좀더부하를주기위해 JMeter User 수를 30 에서 60 으로증가시켜다시테스트를하였다. 당연한결과지만 Minor GC 및 Full GC 수행횟수가증가하였다. 그런데한가지주목할만한점은 Transaction 을수행하는 User 수를두배로설정했으면 TPS 도그에비례하여증가했어야하는데오히려감소했다는점이다. 해당 WAS 의 Thread Pool 을 500 으로잡아놨기때문에충분히처리가가능한 Transaction 양이라로보였지만결과는오히려반대였다. 이는곧해당 WAS 에수용가능한처리량이상의 Transaction 이발생한다면잦은 GC 로인한 Context Switching 및 Suspend 현상으로오히려 TPS 가떨어질수있다는걸의미한다. Part 2 APM 317
Case3 의경우 CMS Collector 가사용되었다. CMS Collector 는기본적으로 Old Area 에 Object 를할당할때 Free list 를사용해단편화를최소화하고 Scheduling 으로 Old Generation 의 Remark 단계가 Minor GC 중간지점에오도록조정하여 OOME 를방지한다. 그리고 Default 로 Old Area 의공간이 68% 이상사용되면 Full GC 가발생한다. 뿐만아니라통계정보를계속산출하기위해지수평균을내는작업도한다. 위의결과를보면 Parallel Collector 에비해오히려 TPS 가낮게나오는걸확인할수있는데이는아마도위와같이간단한테스트환경에서 CMS Collector 의복잡한메커니즘이오히려역작용을한것같다. 유념해야할사실은 CMS Collector 는비교적자원이여유있는상태에서 Size 가큰 Long Lived Object 가있는경우에가장적합하다는것이다. Case4 의경우를확인해보자. Garbage First Collector 를선택했을때이론처럼 Suspend Time 이거의없으며 TPS 도최대치가나올것으로기대했다. 그러나 TPS 가오히려감소한결과를보여준다. 의문이들어여러가지 Statistics 를확인해보았다. 그런데테스트기간동안 CPU 사용량이약 10% 정도꾸준히상승한것이확인되었다. [ 그림 20] Parallel Collector 의 CPU 사용률 [ 그림 21] G1 Collector 의 CPU 사용률 G1 Collector 의경우물리적 Generation 구분을없애고전체 Heap 을 1M bytes 단위 Region 으로재편하여관리를하는데기본적인 Architecture 상 Resource 사용량이다른 Collector 에비해높은것으로확인되었다. G1 Collector 는아직까지실제운영사이트에서사용하는경우를보지못했는데 JDK 7 이안정화되고 JDK 7 에최적화된 WAS 가나와서 G1 Collector 를안정적으로적용할수있는날이온다면 GC 튜닝을안해도되는날이올수있다고한다. 318 2013 기술백서 White Paper
부록 : Train 알고리즘 WAS 처럼짧은트랜잭션처리하는시스템은 GC 로인한 Suspend 현상매우안좋다. 이알고리즘은 Heap 을블록으로나눠 Single Block 단위로 Marking 단계, Copy 단계를한다. Incremental 알고리즘이라고도한다. GC 수행단위가 Single 블럭이므로 GC 중인 Memory 블록만 Suspend 발생한다.(Pause Time 줄인다.) Heap 을 Train 으로구성, Train 은 Car( 객차 ) 라는 fixed Size 의 Memory 블록을묶은체인을말한다. 각 Memory 블록은 Car 외부에서의참조를기억하는 Remember set 을가진다.(Car 외부에서참조하는 Object 의 Object 이름남긴다.) Part 2 APM 319
[ 그림 22] Train 알고리즘구성도 1 에서 Car 1-1 에 GC 발생직전 Mark 를통해 a, b 만 Reachable Object 라고판명되고 c 는 Garbage Object 로구별되었다. Object a 는 Root set R1 에의해직접 Reference 되므로 Remember set 에 R1 이기록된다. Copy, Compaction 을통해 Object 가이동하면주소도변경되며이를참조하는 Object 들도 Reference 변경되어야한다.(Train3 만들어서 ) Object 는자신이참조하는 Reference 는 320 2013 기술백서 White Paper
가지지만, 누가나를참조하는지에대한정보는없다. 최악의경우모든 Root set, Object 의 Reference 모두찾아다녀야한다. Remember set 은작업을방지하며이를구성하기위해서는 write barrier 라는장치를사용한다. write barrier 는간단한코드로된 instruction 의 set, 즉작은이벤트프로그램또는 Trigger 정도라고할수있다. write barrier 는관계를맺을대상 Object 가같은 Car 에있지않으면 Car 에있는 Remember set 에기록한다. Car 1-1 의 Live Object A, B 는 Train 3 만들어서 Car 3-1 로구출된다. Train 1 의마지막 Object 들이 Garbage 상태로순환참조된다.( 음영이들어간네모칸 ) 즉 Car 1-3 을추가해이동이아닌새로운 Train 을만든다. 왜냐하면 A, B 가 Car 1-3 추가해서나갔다면 C 도 Car 1-3 으로이동해야한다. C 는외부참조이므로 Root set 과연결관계모르는상태에서 rescue 범위안에들어오기때문이다. 또 Object C 가 Garbage 인경우 Garbage 를그냥남겨놓아야하는일생긴다. C 는같은 Train 에서참조되고있고 A 는 Train 외부인 root set 에참조되므로 Car 1-3 을추가하는것대신새로운 Train 생성해서옮기는것이다. 정리하면같은 Train 에서참조되면뒤로 Train 을달고, Root set 에서참조되면아예 Train 을새로만든다. 만약 Object C 가 Live 라면 Car 1-1 이 Car 1-3 과동일하게이동해도 Copy 부담만있을뿐이다. 그림의 1 번에서 Object 이동으로비게된 Car 1-1 은 free Car 로변경된다. 그림의 2 에서는 Car 1-2 에 GC 수행하고 Mark 를통해 D, E, F 모두 Garbage 란걸알아낸다. Remember set 의정보로 C 에서 E 를참조하는것도알아내고, 순환참조하는 Object 모두 Garbage 란걸알아내게된다. 별도 Copy 작업없이 1-2, 1-3 모두 free Car 로변경되고 Train1 은 free Train 이된다. Train 알고리즘의장점은 Pause Time 을분산시켜장시간의 Suspend 피할수있다. 단개별 Suspend Time 을합산하면다른알고리즘보다더많아질수있다. Part 2 APM 321