태터데스크 관리자

도움말
닫기
적용하기   첫페이지 만들기

태터데스크 메시지

저장하였습니다.

Java 힙 사이즈 이슈 - Initial Size와 Max Size를 어떻게 설정할 것인가?

Enterprise Java 2007.09.03 15:59
Java Performance Tuning에 있어서 가장 낮은 과일, 즉 가장 손쉽게 설정하고 성능 효과를 거둘 수 있는 것이 Heap 크기와 관련된 설정이다.

그 중에 Initial Size와 Max Size 관련된 설정이 흔히 성능 개선책으로 많이 언급된다.

Sun HotSpt JVM에서의 일반적인 성능 개선 방안은 이렇다.
  • Initial Size와 Max Size를 동일하게 부여해서 동적인 크기 조정에 따른 부하를 없애라.
이 가이드는 너무나 보편적이어서 누구나 의심없이 항상 고려해야할 성능 개선안으로 받아들인다. 하지만 진짜 그럴까?

아마 이 가정에 대해서 의심을 해보거나 실제로 테스트를 해 본 사람은 거의 없을 것으로 생각된다.

하지만, 큰 Initial Size는 오히려 어플리케이션의 초기 성능을 떨어뜨리는 원인이 될 수 있다. Initial size가 크면 초기 Minor GC와 Major GC에 불필요하게 많은 시간이 소모된다.

반면 Initial Size가 적절히 작으면 초기 Minor GC와 Major GC가 아주 짧게 끝나고 필요할 때 메모리가 확장(Expansion)되므로 오히려 부하가 적다.

아래 테스트 결과를 보자
Case1: java -Xms32M -Xmx512M
Full GC: Pause Time = 5.364361, Count = 16, Average=0.335273
Minor GC: Pause Time = 9.769008, Count = 303, Average=0.032241

Case2: java -Xms512M -Xmx512M
Full GC: Pause Time = 4.609964, Count = 13, Average=0.354613
Minor GC: Pause Time = 10.253730, Count = 259, Average=0.039590

일반적인 성능 개선 추전안과 거꾸로 Initial Size를 작게 한 경우에 오히려 GC에 의한 부담이 작은 것을 확인할 수 있다. 그 이유는 아래와 같이 초기 GC 시간이 작기 때문이다.

Case1:
0.000: [GC 0.000: [DefNew: 2944K->320K(3264K), 0.0061382 secs] 2944K->1298K(32448K), 0.0062603 secs]
0.014: [GC 0.014: [DefNew: 3259K->320K(3264K), 0.0050409 secs] 4237K->2280K(32448K), 0.0051333 secs]
0.023: [GC 0.023: [DefNew: 3264K->320K(3264K), 0.0077398 secs] 5224K->3236K(32448K), 0.0078449 secs]
...
19.840: [GC 19.840: [DefNew: 26176K->2879K(26176K), 0.0233516 secs] 125359K->105130K(258248K), 0.0234460 secs]
19.882: [GC 19.882: [DefNew: 26175K->2879K(26176K), 0.0380722 secs] 128426K->112633K(258248K), 0.0381711 secs]
19.939: [GC 19.939: [DefNew: 26175K->2879K(26176K), 0.0392069 secs] 135929K->120141K(258248K), 0.0392966 secs]

Case2:
0.000: [GC 0.000: [DefNew: 23360K->2880K(26240K), 0.0337995 secs] 23360K->7461K(259264K), 0.0338926 secs]
0.052: [GC 0.052: [DefNew: 26240K->2879K(26240K), 0.0412854 secs] 30821K->14526K(259264K), 0.0413726 secs]
0.113: [GC 0.113: [DefNew: 26239K->2880K(26240K), 0.0406367 secs] 37886K->21559K(259264K), 0.0407367 secs]
...
19.741: [GC 19.741: [DefNew: 23360K->2879K(26240K), 0.0307106 secs] 98231K->82374K(259264K), 0.0307986 secs]
19.789: [GC 19.789: [DefNew: 26239K->2879K(26240K), 0.0393455 secs] 105734K->89908K(259264K), 0.0394374 secs]
19.848: [GC 19.848: [DefNew: 26239K->2879K(26240K), 0.0403141 secs] 113268K->97442K(259264K), 0.0404032 secs]

물론 위의 테스트 시나리오가 너무나 심플해서 복잡한 어플리케이션에서 상황을 재현하지 못한다. 또한 수행시간이 길어지면 초기 구동 성능이 차지하는 비중이 작아지므로 역시 의미가 없다(하지만 이 경우 Initial Size를 크게 주는 것 또한 전혀 의미가 없기는 마찬가지다. 어차피 Heap은 Max Size까지 커질 테니까...)

하지만 엄밀한 테스트와 해석이 없는 교조적인 튜닝 가이드는 무의미하다는 것을 잘 보여준다.

재미있게도 IBM에서 제공하는 JVM 튜닝 가이드에서는 Initial Size와 Max Size를 같이 하지 말고 Initial Size를 작게 지정하라고 권고하고 있다. IBM JVM은 전통적으로 Sun HotSpot JVM과는 전혀 다른 Heap 관리 기법을 사용하기 때문에 이런 가이드가 나온 것으로 이해할 수 있다.(이유는 나중에 기회가 되면 상세하게...)





신고
tags : , ,
Trackback 0 : Comment 0

Write a comment

티스토리 툴바