(참조 : https://medium.com/zaloni-engineering/troubleshooting-high-cpu-and-memory-leaks-in-java-processes-fa962775351d://www.eginnovations.com/blog/troubleshoot-java-cpu-issues/
https://www.theserverside.com/answer/How-to-fix-high-Java-CPU-usage-problems
https://middlewareworld.org/2020/09/12/how-to-troubleshoot-java-cpu-usage-issues-in-linux/)
1. cpu load 가 높은 process 찾기
top -b -d 10 -b | grep "load average" -A 15
2. cpu 점유울의 원인은 java 프로그램이라는 것을 확인
3. cpu load 가 높은 pid의 하위 pid 들 확인
top -n 1 -b -H -p <pid> | head -15
3. jstack 을 통해서 해당 쓰레드가 어떤 부분인지 확인...(16진수로 변환)
jstack [pid] | grep [쓰레드아이디 16진수]
4. 이런식으로 죄다 waiting condition 들이었고, 다른 쓰레드의 영향으로 대기상태의 쓰레드가 많아서 인걸로 판단..
5. https://www.theserverside.com/answer/How-to-fix-high-Java-CPU-usage-problems 이글을 읽어 보니, cpu 사용률을 많이 차지 하는 쓰레드가 직접적인 원인의 지표로 판단하기 어렵다는 판단. 잦은 GC가 원인이 아닐까 생각해봄.
그래서 힙덤프를 뜸
6. 이클립스 메모리 분석기(mat)을 통해서 많은 양의 ArrayList 를 loop 로 가져오는 부분에 메모리 릭이 발생한다는 것을 알게 됨.
이후 문제 해결 결과
1) 쓰레드 덤프 결과 cpu 사용율이 높은 곳은 카우치 베이스에서 데이터를 가져오는 dao 부분이었다.
정확히는 document 조회 결과 json 스트링을 object에 매핑 하는 부분인데, document에 포함되어 있는 집합 데이터(array 형태의 데이터 필드들)을 모두 포함한 결과를 가져오는 부분을 너무 자주 조회하고 있었다.
한번만 호출해서 가져와도 되는 정보를 다른 서비스의 메소드들을 호출 하면서 중복으로 호출 되는 부분이 많았고, 해당 document 의 모든 정보가 필요한것도 아닌데 모든 정보를 호출 하는 것도 문제였다.
반복으로 호출 하는 부분을 한번 호출로 개선하고, dao 메소드를 용도 별로 세분화해서 필요한 정보의 부분만 조회해 오도록 수정 하였더니, jvm 뿐 아니라 웹서버 <-> 카우치베이스간 트래픽이 줄어 cpu 점유율이 확 낮아졌다.
2) 위 1번 외에도 힙덤프를 통해서 메모리 릭이 발생하는 부분을 확인해 데이터의 갯수를 응답해주는 api 에서 조회결과 list.size 로 응답해오는 부분 확인, list에 담을 필요 없이 count만 조회하는 것으로 변경...jvm gc 폭이 줄어들면서 cpu 점유율이 한단계 더 줄어듬.
'java' 카테고리의 다른 글
adopJDK 설치 (0) | 2022.07.24 |
---|---|
openJDK와 adoptJDK의 차이점 (0) | 2022.07.24 |
openjdk 'GA' 의미 (0) | 2022.05.17 |
java list slice 성능 비교 (0) | 2022.05.11 |
쓰레드, 힙덤프 생성 (0) | 2022.04.27 |
댓글