티스토리 뷰

 프로젝트가 막바지에 이르고 있어서 요즘은 테스트를 진행하고 있는데, 지난 프로젝트(엑셀업로드를 통한 대량등록 성능 개선의 건)를 통해 대용량 데이터를 다루는 경우를 항상 염두에 둬야 한다는 것을 배웠기 때문에 이번에도 테스트데이터로 150만건 정도를 준비했다. 데이터를 150만건이나 만들려고 보니 프로그램으로 돌리는게 빠르겠다싶어서 대용량 더미데이터를 만들어주는 프로그램을 짰다. 그래서 그 데이터로 테스트를 하다가... out of memory(GC Overhead limit exceed)를 만났다.

 대리님께 이 기능에서 out of memory가 발생한다고 말씀드렸더니 Jmap, Jhat으로 메모리 덤프 분석해서 원인을 찾아보라고 하셨다. Jmap과 Jhat을 처음 들어서 찾아보니 Jmap은 JVM 모니터링할 수 있는 도구이고, Jhat은 Java Heap Analysis Tool이었다.

 이제 1. 덤프를 생성해서 2. 분석하면 된다. Jmap과 Jhat이 뭔지는 알겠어도 덤프를 떠보는건 처음이라 어떻게 해야 하나 어버버해서 인터넷의 도움을 많이 받았다.

덤프 생성

 먼저 PID를 알아야 했다. 그래서 아래 명령어로 JVM 프로세스의 PID를 구했다.

jps -v

 위 명령어를 입력했을 때  나의 경우 Jps와 Bootstrap 두 가지 항목이 표시됐는데 그중 Bootstrap의 PID를 사용하는거였다.(다른 사람들이 하는 걸 보면 이 부분의 이름이 다른 것 같은데 왜 다른건지?)

 그래서 알아낸 PID로 해당 기능을 실행하고 out of memory가 뜨기 직전에 다음의 명령어를 실행했다.

jmap -dump:live, file=<file-path> <pid>

 그리고 해당 경로에 생성된 파일을 내 컴퓨터로 옮겨서(개발계에서는 여러 가지 문제로 열어볼 순 없으니까) MAT를 설치하고 열어보았다. (이곳으로 들어가서 원하는 버전의 Update Site 항목의 주소를 복사해서 이클립스의 Install New Software 메뉴를 이용해서 설치하면 된다.)

분석

 처음에 이 화면을 보고 좀 당황했다. 쉽게 설명하자면, 저 원형 그래프가 메모리를 나타내고, 메모리 중 비중을 많이 차지하는 것들을 중점적으로 보면 된다. 아래의 Problem Suspect에 표시되듯이, 제일 큰 비중을 차지하는 것이 51.91%의 Jdbc의 ResultSet이었고, 그 다음이 45.89%의 객체였다. 노란 설명칸 아래의 'Details >'를 클릭하면 자세한 설명을 볼 수 있다.

 나의 경우, Problem Suspect1의 Details를 눌렀는데 아래와 같이 표시됐다. 그리고 익숙한 저 Number of Objects의 숫자... 내가 준비한 데이터 수와 거의 일치했다. 여기서부터 문제의 원인이 보이기 시작했다.

 Problem Suspect2의 Detail을 눌렀을 때 데이터가 매핑되는 DTO여서 데이터를 가져오는 부분에서 문제겠구나 더 확신이 들었다.

 메모리에 한번에 준비한 데이터건수가 다 올라가려면 DB에서 한번에 읽어오는 경우일거라고 생각해서 DB에서 읽어오는 코드를 살펴봤다. 그랬더니 페이징 처리해서 취합하는 방식으로 되어있었다. 페이징 처리시 취합된 데이터는 다 클리어처리를 해줘서 한번에 데이터건수가 전부 잡힐 이유가 없어보였는데, 매퍼의 쿼리를 보고 단번에 알아차릴 수 있었다. 쿼리조건상 페이징처리 쿼리를 탈 수 없는 상황이었다. 그래서 이 부분을 수정해주고 실행하니 잘 수행되는 걸 확인할 수 있었다.

 우리 팀장님은 항상 메모리 관리 얘기를 많이 하신다. 나는 그 얘기가 중요하다는걸 알지만 내가 직접 이렇게 메모리 분석을 해본 적이 없으니 와닿지 않았다. 그런데 이번 기회에 이렇게 메모리 분석을 해보니 팀장님이 하신 말씀이 더욱 와닿는다.

 변수값 하나 때문에 쿼리가 제대로 실행되지 않았고, 그게 결국 out of memory로 이어졌다. 만약 150만건정도의 대량 데이터로 테스트를 하지 않았다면 누구도 이상하다고 생각하지 않은 채 넘어갔을지도 모른다. 이번 기회를 통해 기능을 구현하고 잘 돌아가는지 테스트할 때 (원래도 하긴 했지만) 쿼리도 예상한대로 돌아가는지 면밀하게 살펴야겠다고 생각했다. 그리고 지난 경험을 통해 대용량 데이터를 다루는 경우를 염두에 두고 대용량 데이터를 만들어서 테스트해보길 정말 잘했다고 생각했다. 이를 통해서 파일업로드와 처리에 정확한 기준을 만들 수 있게 되었다.

 그리고 한 가지 더. 항상 많은 데이터를 넣고 테스트해야만 문제를 찾을 수 있다는 것은 말이 안된다. 모니터링 툴을 사용하는 방법을 배워보고 더 나아가 팀에 도입할 수 있다면 제안하는 것도 좋겠다는 생각이 들었다.

 마지막으로 메모리 덤프도 분석했는데 별 다른 문제를 찾지 못했다면 어떻게 해야하나하는 생각이 든다. 그때는 메모리를 늘려주는 것이 좋겠지?

300x250
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
글 보관함