Post
KO

요즘 여러가지 생각 및 경험 GC 적용 포함

대용량 처리 관련 질문들이 두루 있다.

(내 개인적인 생각이기 때문에 이후에 잘못된 내용이 있으면 추가하도록 하겠다,)

gc 옵션을 얼마나 줬느냐, 사이즈를 어떻게 했느냐, thread dump를 분석해봤느냐 이런 질문들..

평소에 개발하는 일로는 경험할 일이 없다고 생각한다.

왜냐하면 별도 설정 없이 잘 작동하고, 위의 질문 처럼 부하가 치닫는 일은 잘 없기 때문이다.

이런 내용은 성공한 포털 사이트나 성공한 서비스를 다루지 않는 회사라면 더더욱 그렇고, 그런 회사들은 소수이다.

나는 대규모 트래픽은 아니고 나름 대용량 처리를 하면서 위와 같은 질문들에 대한 것들을 경험할 수 있었다.

1. heap memory.

자바 성능 튜닝 이야기 책을 읽어보면 heap 사이즈 조절과 GC 옵션들 그리고 jvm 메모리 관련된 사항들에 대해서 잘 설명해주고 있다. perm 영역과 heap 영역이 있는데 자세히 들어가보면 young 영역, old 영역, suvivor1,2가 존재한다.

perm영역은 class가 컴파일된 정보를 담고 있는 영역이고 heap 영역은 코드 상의 객체 생성을 할 때 사용되는 메모리 영역이다. (java 8 이후로는 metaspace로 변경되에 gc option에는 metaspace로 줘야 한다.)

그리고 perm 영역은 고정이지만 heap 영역은 사용량에 따라 옵션으로 설정해준 heap 사이즈대로 줄어들고 늘어나며, 초과할 때 GC가 돌아서 메모리를 확보하는 것이다.

GC가 도는 작업을 java에서는 stop the world라고 하고, 모든 작업들이 중단된다.

heap 사이즈가 크면 큰 만큼 소요시간이 오래걸리고, heap 사이즈가 작으면 작은 만큼 자주 일어나기 때문에 자주 중단될 것이다.

이런 GC가 도는 상황이 곧 성능저하가 될 수 있는 부분이다.

따라서 적절하게 heap 사이즈를 지정하고 모니터링을 한다.

(물리 메모리의 50%를 할당을 시킨다. 이유는 OS 상에서 OOM killer가 죽일 수 있으니..)

이때 지정한 heap 사이즈가 넘게되면 dump를 떠서 memory leak이 발생되는지 확인해보면 문제를 알 수 있다.

GC 셋팅 중 이야기 하는 것들은 g1gc가 젤 무난하게 사용할 수 있다고 한다.

그리고 모니터링 해보면 gc가 발생될 때마다 cpu가 사용량이 100% 되면서 작업이 멈추는 듯한 것들을 확인할 수 있다.

2. core 및 thread

thread 수를 한정적으로 설정하는 부분이 많은데 개인 적으로 코어 수에 맞춰서 thread 갯수를 맞추거나, core 수 * 2 정도 사용한다. 뭐가 정답이다 알 수 없지만, 각 코어 들의 효율적으로 활용 할 수 있도록 맞춰놔야 한다고 생각한다. core가 잘 사용되는지 확인 하는 것은 htop 이나 nmon등을 설치하면 모니터링 할 수 있다.

3. 네트워크 대역폭

서버 spec이 중요하긴 하지만, 서버 간 통신으로 돌아간다면 네트워크 대역폭을 확인해야 한다.

데이터 크기와 전송 속도를 확인하고, 테스트 진행 시 서버 spec보다 performance가 나오지 않는다면 network을 확인해봐야 한다. aws의 instance들 중에서는 가장 높은 spec의 instance가 25G 정도 나오니 참고해서 해야 한다.

4. DISK I/O

I/O작업이 빈번한 Database 그 밖의 장비에 있는 disk 의 i/o를 확인해보는 것이 좋다. i/o 성능에 따라 데이터 입력등이 병목되어서 늦게 들어갈 수 있다.

5. 메시지 통신 간 압축

메시지 통신간 대역폭이 제한되어 느리다면, 데이터 압축을 통하여 보내는 것을 고려해봐야 한다.

메시지를 압축하게 되었을 때, 받는 쪽에서는 압축을 풀고 데이터를 얻어야 함으로 cpu를 더 사용하게 되는 trade off가 있다는 것을 생각하자.

아주 짧은 지식으로는 이정도로 마무리 해야겠다. 나의 갓 개발자가 1번째 리뷰를 하고 댓글을 달아줄 것이다.

jvm 적용 옵션

nohup java -verbose:gc \ -Xloggc:gc.log \ -XX:+UseG1GC \ -XX:+PrintGC \ -XX:+PrintGCDetails \ -XX:+PrintGCTimeStamps \ -XX:+HeapDumpOnOutOfMemoryError \ -XX:HeapDumpPath=heapdump.bin \ -XX:+UseStringDeduplication \ -jar -Xms3g -Xmx3g \ -Dspring.profiles.active=stage demo.jar > /dev/null 2>&1 & echo $! > run.pid

콘솔 로그 출력

-verbose:gc

상세한 GC 로그

-XX:+PrintGCDetails

날짜/시간 기준의 GC 로그

-XX:+PrintGCDataStamps

자동 heap 덤프 생성

-XX:+HeapDumpOnOutOfMemoryError

heap 모니터링 도구

jstat

jmap

jmap -histo

jhat

  • jhat은 jmap -dump 옵션을 통해 성성한 Heap 덤프 파일을 분석한 후 그 결과물을 HTML 형태로 제공해주는 도구이다. 따라서 웹 브라우저를 통해 결과물을 확인 할 수 있다.
jmap -dump:format=b,file=heapdump.dump jhat heapdump.dump

GC 관련 사항은 아래 링크에 잘 정

Java 시스템 운영 중 알아두면 쓸모 있는 지식들

안녕 프로그래밍

리되어 있다.

https://www.holaxprogramming.com/2017/10/09/java-jvm-performance/

This article is licensed under CC BY 4.0 by the author.