
HeapDump는 JVM 힙 메모리 상태를 파일로 추출한 것 입니다.
애플리케이션이 실행 중인 시점의 힙 메모리 구조와 내용을 분석할 수 있습니다.
보통 메모리 누수나 과도한 메모리 사용등의 문제를 디버깅할 때 사용합니다.
서버에서 HeapDump를 뜨는 방법은 여러가지가 있는데, 저는 http 엔드포인트를 만들어 사용합니다.
대표적으로 Spring에서 제공하는 Actuator가 있습니다, 하지만 주의해서 사용해야합니다, 우아한 형제들 참고 https://techblog.woowahan.com/9232/
Actuator를 설정하고 /actuator/heapdump 경로로 http 요청을 하게 되면 파일을 다운받게 됩니다.

이렇게 힙 덤프를 분석해주는 프로그램을 사용해서 분석을 진행하면 됩니다, 저는 Eclipse의 MAT를 주로 사용해요
이런 응용 프로그램을 이용하여 메모리 누수 검사나 기타 등등 작업을 진행할 수 있습니다, MAT의 자세한 사용법은 장애 회고하는 다른 글에서 다뤄보도록 하겠습니다.
모든 HeapDump가 production 환경에서 장애가 일어났을때 분석하기 위해 사용되지는 않습니다.
개발 및 테스트 과정 도중에 응답시간이 지연되거나 대용량 데이터를 처리하는 API를 만들고 테스트 하는 과정에서 로컬 환경에서도 Heap을 분석할 상황들이 많이 생깁니다.
특히 어드민 API를 만들 때 데이터를 전체 조회하는 API를 많이 만들게 되는데, 뭔가 미심쩍잖아요?
개발하는 과정에서 힙 사용량을 보고 코드를 몇번 개선해서 PR을 날린다면?
아직 명확히 좋은 코드가 뭔지는 모르는 레벨이여도 말도 안되는 코드를 짜는 일은 방지할 수 있을겁니다.
하지만 AI한테 물어봐서 이해도 못하는 방법으로 개선하지는 말아주세요.

그래서 오늘 소개할 로컬에서 Heap을 분석하기 위한 프로그램은? 바로 바로 Visual VM입니다!
https://visualvm.github.io/download.html

프로그램을 열게 되면 위처럼 현재 로컬에서 돌아가고 있는 자바 프로세스들을 감지해서 리스트업 해줍니다!
분석하고 싶은 프로세스를 더블클릭해서 Monitor 탭을 보면 여러분들도 간편하게 로컬에서 heap 분석을 할 수 있어요.

이렇게 실시간으로 로컬의 어플리케이션에서 heap 사용을 모니터링 할 수 있고 오른쪽 위의 Perform GC를 이용해서 강제로 GC를 발생시키거나 HeapDump를 추출 할 수 있습니다.
이렇게 하고 글을 마무리한다면 재미가 없겠죠? 케이스를 하나 보여드리겠습니다.

실제로 어드민에서 사용할 API를 cursor를 이용해서 쓱쓱 개발 중 조회가 엄청 느린 페이지가 있길래 메모리를 많이 사용해서 1 호출 1 GC가 발생하고 있었다.. GC가 이븐하지 않죠?
코드를 살펴보니 테이블 전체를 Entity로 조회하고 service단에서 dto로 전체 map을 치고 있었다
그래도 ai가 제안하는 코드를 살펴보면서 적용했는데 이런 실수를.. 얼른 코드를 개선했습니다.
여러 개선 방법중에 일단 DTO Projection을 사용했다, 어드민을 사용하는데 불편하지 않을 정도로 개선되었어요.
사실 페이징이 가장 근본적인 해결 방법이지만 실무에서는 비즈니스적 요구사항이나 특수성 때문에 페이징을 도입하기 어려운 경우도 많고 항상 비즈니스적 제약과 시간 투자, 성능 사이에서 고민합니다.
이번 케이스는 DTO Projection으로 p95 latency를 5초 이내로 안정시킬 수 있어서 여기까지만 했습니다.
예전에는 JVM 관련된 지식들을 습득하고 활용하는것이 먼 세상 일처럼 느껴지고 언제 어떻게 공부해야할지 걱정이였는데 정작 서비스를 개발하면서 알고 싶지 않아도 자연스럽게 문제 해결을 위해서 알게 되었습니다.
개발을 위한 서비스가 아닌 서비스를 위한 개발, 즉 문제해결을 주 역량으로 설정하고 천천히 다양한것들을 경험하다보면 다들 언젠간 경험할 영역이니 당장 HeapDump를 뜰일이 없다고 조급해하고 억지로 끼워맞추려고 하지 않아도 괜찮습니다.
중요한건 문제 해결입니다, 다들 각자의 위치에서 현재 하고 있는 경험안에서 최대한 슬기로운 방법으로 문제해결을 하도록 노력하는게 제일 중요한 가치라고 생각합니다.