Java

Heap 메모리 할당에 따른 GC 횟수 확인, 그리고 대량 조회

빅토르최·2014년 9월 22일·조회 8,494

1. 개요

Heap 메모리 할당에 따라, 부하가 있을 때, GC 횟수에 어떠한 차이가 있는지 확인해 보고자 한다.


2. 실험환경

  • JDK 1.7 64bit
  • Tomcat 8.0.12
  • jPetstore 애플리케이션

3. 실험조건

  • 요청 유형은 조회 + 로그인 + 장바구니 등이 혼합된 총 5000건

4. 실험결과

Heap Tomcat 기동시간(초) 요청처리시간(초) 초당처리건수 GC횟수 FullGC횟수
64m 61224 2194 2.279 569 380
128m 13473 2167 2.307 245 4
256m 13131 2162 2.313 123 0
512m 13814 2164 2.311 62 0
1024m 13014 2163 2.312 32 0
2048m 13343 2165 2.309 16 0
4096m 13140 2165 2.309 9 0
  • Heap 64m인 경우는 Tomcat 기동에 약 1분 소요되나, Heap 128m 이상인 경우 약 13초 정도로 Tomcat 기동 시간에 큰 차이가 없었음
  • GC 횟수로 볼 때 할당 메모리에 정비례하여 줄어드는 것을 확인할 수 있었음
  • 이 테스트에서 Heap 256m 이상에서 Full GC는 전혀 발생하지 않았음
  • 이 테스트에서 초당처리건수를 볼 때 전체적으로 큰 차이는 없었음
  • 다만, 테스트 결과에 나타나지 않은 서버/프로세스 CPU 사용률을 확인할 필요가 있음 (GC = CPU 사용)

5. 대량 조회

  • 응용 시스템에서 대량 조회가 발생할 때, 과연 WAS, JVM 레벨에서만 대응하는 것은 옳지 않다. 응용 시스템 레벨에서는 다음과 같이 대응할 필요가 있다.
  • Framework에서 특정 건수 이상에서는 멈추도록 조치 (Exception 처리)
  • 데이터 조회 제한 : 비즈니스적으로 1) 조회가 꼭 필요한지, 2) 필요하다면 조회 범위 축소가 가능한지 확인
  • 페이징 처리 : DB 처리 부하를 줄이는 것이 핵심
    예) 건수와 데이터 처리를 분석함수를 이용하여 한 문장으로 실행할 수 있도록 처리 (스칼라 쿼리는 실제 건수만큼만 수행)
  • 대량 조회 전용 WAS 구성
  • 대량 데이터 업/다운로드 시 HTTP 출력 스트리밍과 JDBC ResultSet을 연동하여 처리
  • 메커니즘 변경
    - MyBatis ResultHandler + Jackson 사용
  • 엑셀 처리 시 매커니즘 변경
    - 업로드 : MyBatis ResultHandler + POI BufferedStream (SAX) 방식 사용
    - 다운로드: BufferedStreaming (SXSSF) 방식 사용

댓글 3

로그인 후 댓글을 남길 수 있습니다.

  • stdio.hstdio.h· 2014년 10월 3일
    어느 실험 case에서나 할당한 heap 용량과 gc 횟수를 곱하면 대략 30,000 가까운 값이 나오고 있네요. 결국 30,000m = 30g 정도의 메모리가 필요한 상황이었다고 생각해도 될까요? 4096m에서 두배 올려서 8192m로 할당했다면 gc는 4~5회 정도만 했을 것 같고.
  • 몽상가몽상가· 2014년 10월 13일
    무조건 heap이 크다고 성능이 좋은건 아니네요. 테스트 결과 잘 봤어요~
  • 빅토르최빅토르최· 2014년 11월 6일
    몽상가/ 결국 메모리 할당량과 CPU 사용률은 반비례가 아닐까 싶은데, 적정값은 모든 애플리케이션마다 다르겠지요.