Skip to content

chore: JVM 메모리 설정 및 Hibernate 쿼리 플랜 캐시 축소#536

Merged
dh2906 merged 2 commits intodevelopfrom
chore/optimize-jvm-memory
Apr 13, 2026
Merged

chore: JVM 메모리 설정 및 Hibernate 쿼리 플랜 캐시 축소#536
dh2906 merged 2 commits intodevelopfrom
chore/optimize-jvm-memory

Conversation

@dh2906
Copy link
Copy Markdown
Contributor

@dh2906 dh2906 commented Apr 13, 2026

🔍 개요

  • 해당 프로젝트의 서버 메모리 사용량은 약 500MB를 차지하는 중 image

  • 프로젝트 규모에 비해 너무 많은 메모리를 사용한다고 판단하여 원인 파악을 시작

  • 힙 덤프 분석 결과 실제 힙 사용량은 약 85MB로, 원인은 힙이 아닌 다른 영역에 있을 것이라 추측
    image

  • 또한 무엇인지 모르는 ATNConfig의 힙 사용량이 5%나 차지하는 것을 관측

원인

  • 힙 덤프 분석 결과 실제 힙 사용량은 약 85MB로, 나머지 415MBMetaspace, Thread Stacks, JVM 내부 메모리 등에서 사용 중

  • 원인:

    • DockerfileJVM 메모리 설정(-Xmx 등)이 없어 JVM이 기본값으로 과도한 메모리를 예약
      • 기본적으로 컨테이너 단위로 2GiB를 차지하는데, 따로 설정이 없으면 1/4 크기로 지정됨
    • Hibernate HQL 파서(ANTLR4)의 ATNConfig 객체가 132,873개 누적되어 약 4.25MB 점유
    • Hibernate Query Plan Cache 기본 크기(2048)가 과대 설정

🚀 주요 변경 내용

Dockerfile

  • -Xms128m / -Xmx256m: 힙 메모리 상하한 고정하여 과도한 메모리 예약 방지
  • -XX:MaxMetaspaceSize=128m: Metaspace 상한 설정
  • -XX:+UseStringDeduplication: 중복 String 인스턴스(210K개) 메모리 절약
  • -XX:+AlwaysPreTouch: 시작 시 힙을 물리 메모리에 미리 할당하여 런타임 지연 및 OOM 조기 발견
  • -Xlog:gc*:file=/app/gc.log:time,uptime,level,tags:filecount=5,filesize=10m: GC 로그 순환 저장
  • -XX:+HeapDumpOnOutOfMemoryError / -XX:HeapDumpPath=/app/heapdump.hprof: OOM 발생 시 자동 힙 덤프 생성

application-db.yml

  • hibernate.query.plan_cache_max_size: 2048 → 64

    • Hibernate가 HQL/JPQL 쿼리를 실행할 때 ANTLR4로 파싱한 실행 계획(Query Plan)을 캐시에 저장하는데, 이 캐시에 유지할 최대 실행 계획 수
    • 기본값 2048은 고유 쿼리가 많지 않은 서비스에서 과도하여, 사용하지 않는 파서 객체(ATNConfig)가 메모리에 누적됨
    • 자주 사용하는 쿼리 64개만 캐시에 유지하고 나머지는 GC가 회수하도록 축소
  • hibernate.query.plan_parameter_metadata_max_size: 128 → 32

    • 실행 계획과 함께 캐시되는 파라미터 메타데이터(바인딩 타입, 순서 등)의 최대 보관 수
    • plan_cache_max_size와 비율을 맞추어 함께 축소

💬 참고 사항

  • OOM 가능성: 힙이 256MB로 제한되므로, 트래픽 급증 시 OOM이 발생할 수 있음. 발생 시 -Xmx 값 증량 필요

✅ Checklist (완료 조건)

  • 코드 스타일 가이드 준수
  • 테스트 코드 포함됨
  • Reviewers / Assignees / Labels 지정 완료
  • 보안 및 민감 정보 검증 (API 키, 환경 변수, 개인정보 등)

- Xms128m/Xmx256m으로 힙 메모리 상하한 고정하여 과도한 메모리 예약 방지
- MaxMetaspaceSize=128m으로 Metaspace 상한 설정
- UseStringDeduplication으로 String 중복 제거로 메모리 절약
- AlwaysPreTouch로 시작 시 힙을 물리 메모리에 미리 할당
- GC 로그를 순환 파일로 저장하여 OOM 원인 파악 가능
- HeapDumpOnOutOfMemoryError로 OOM 발생 시 자동 힙 덤프 생성
- Hibernate query plan cache를 2048→64로 축소하여 ATNConfig 파서 객체 누적 방지
@dh2906 dh2906 self-assigned this Apr 13, 2026
@dh2906 dh2906 added the 배포 운영 서버의 배포 관련 이슈입니다. label Apr 13, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 13, 2026

Warning

Rate limit exceeded

@dh2906 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 3 minutes and 18 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 3 minutes and 18 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 5a57a593-e164-4128-a2f8-72e4c83b52b1

📥 Commits

Reviewing files that changed from the base of the PR and between f1df8a8 and 959409c.

📒 Files selected for processing (1)
  • Dockerfile
📝 Walkthrough

개요

Dockerfile의 JVM 시작 명령어에 메모리 할당, 메타스페이스 제한, 문자열 중복 제거, GC 로깅, 힙 덤프 설정 등의 런타임 플래그를 추가했습니다. 또한 Hibernate 쿼리 캐시 튜닝 속성을 application-db.yml에 추가했습니다.

변경 사항

Cohort / File(s) 요약
JVM 런타임 설정
Dockerfile
컨테이너 시작 명령어에 JVM 플래그 추가: 힙 크기(-Xms128m, -Xmx256m), 메타스페이스 제한(-XX:MaxMetaspaceSize=128m), 문자열 중복 제거(-XX:+UseStringDeduplication), 메모리 사전 할당(-XX:+AlwaysPreTouch), GC 로깅(/app/gc.log), OOM 힙 덤프 설정.
데이터베이스 튜닝
src/main/resources/application-db.yml
Hibernate 쿼리 캐시 튜닝 속성 추가: plan_cache_max_size=64, plan_parameter_metadata_max_size=32.

예상 코드 리뷰 소요 시간

🎯 2 (Simple) | ⏱️ ~8분

관련 가능성 있는 PR

시 🐰

메모리 정렬하고 힙을 정돈했네,
GC 로그는 차곡차곡 쌓이고,
캐시는 스마트하게 줄였어,
런타임이 쌩쌩 날아다니길! ✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed PR 제목이 Dockerfile의 JVM 메모리 설정과 application-db.yml의 Hibernate 쿼리 플랜 캐시 축소라는 주요 변경사항을 정확히 요약하고 있습니다.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description check ✅ Passed PR 설명이 변경 사항과 명확히 관련되어 있으며, 메모리 최적화의 필요성, 원인 분석, 그리고 구체적인 변경 내용이 상세히 기술되어 있습니다.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/optimize-jvm-memory

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@Dockerfile`:
- Line 26: Remove the JVM flag "-XX:+AlwaysPreTouch" from the Dockerfile JVM
options list because it forces full heap page allocation at startup (increases
startup time and RSS); locate the place where JVM arguments are assembled (the
entry containing the string "-XX:+AlwaysPreTouch") and delete that flag (or
conditionally omit it for production images) so the JVM uses the default
behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 1f0f44e4-794c-46a8-9cfb-1c8230714cb3

📥 Commits

Reviewing files that changed from the base of the PR and between 0ed5604 and f1df8a8.

📒 Files selected for processing (2)
  • Dockerfile
  • src/main/resources/application-db.yml
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Code Style Check
  • GitHub Check: Analyze (java-kotlin)
🧰 Additional context used
📓 Path-based instructions (1)
**/*

⚙️ CodeRabbit configuration file

**/*: 공통 리뷰 톤 가이드:

  • 모든 코멘트는 첫 줄에 [LEVEL: ...] 태그를 포함한다.
  • 과장된 표현 없이 사실 기반으로 작성한다.
  • 한 코멘트에는 하나의 이슈만 다룬다.
  • 코드 예시가 필요하면 최소 수정 예시를 제시한다.
  • 가독성/단순화/확장성 이슈를 발견하면 우선순위를 높여 코멘트한다.

Files:

  • src/main/resources/application-db.yml
  • Dockerfile
🔇 Additional comments (1)
src/main/resources/application-db.yml (1)

28-30: [LEVEL: INFO] Hibernate 쿼리 플랜 캐시 축소 설정은 변경 목적과 일치합니다.

Line 28-30 설정 경로(spring.jpa.properties.hibernate.query.*)와 값 선언이 일관되어, 메모리 절감 목적의 튜닝 변경으로 자연스럽습니다.

Comment thread Dockerfile Outdated
- 시작 시 전체 힙 페이지를 물리 메모리에 할당하여 시작 시간과 RSS 증가
- 기본 lazy allocation 동작으로 되돌림
@dh2906 dh2906 merged commit 0fe2411 into develop Apr 13, 2026
4 checks passed
@dh2906 dh2906 deleted the chore/optimize-jvm-memory branch April 13, 2026 05:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

배포 운영 서버의 배포 관련 이슈입니다.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant