Bldev's Blog

[JPA] 영속성 컨텍스트 메모리, 100만 건 조회

2026. 10. 6.

대량 조회 시 영속성 컨텍스트에 엔티티가 쌓여 힙 부하가 생긴다. 아래 블록은 같은 조건에서 그 부하의 크기, OOM이 나는 조건, 대안이 부하를 얼마나 줄이는지를 보여준다.

새 엔티티를 하나의 영속성 컨텍스트에서 계속 저장하면 트랜잭션이 끝날 때까지 모든 엔티티가 관리 상태로 남는다. 필요한 메모리는 엔티티 상태, 연관관계, 영속성 컨텍스트의 관리 정보에 따라 달라지므로 객체 수만으로 안전한 힙 크기를 정할 수 없고, JVM의 최대 힙이 작으면 OutOfMemoryError가 발생할 수 있다. 최대 힙을 지정하지 않으면 64비트 서버 JVM은 가용 메모리의 1/4을 최대 힙으로 잡는다. 100만 건을 조회하면 영속성 컨텍스트가 엔티티만 보유할 때보다 힙을 더 많이 점유한다.

2026-10-07
영속성 컨텍스트 메모리, 100만 건 조회
  • 일반 조회로 100만 건을 읽으면 영속성 컨텍스트가 힙 786MB를 차지했다. 엔티티만 메모리에 올려 둘 때(535MB)의 약 1.5배다.
  • 힙을 700MB로 제한하면 OOM이 났고, 900MB에서는 성공했다.
  • scroll과 clear, StatelessSession, select sum 집계는 힙 64MB에서도 처리됐고 힙 점유량은 약 15~20MB였다.
측정 상세 펼치기접기

환경

프레임워크
Hibernate ORM 6.4.4.Final
데이터베이스
H2 2.2.224 (임베디드, 파일 DB)
JVM
OpenJDK 17.0.18, G1 (기본값)
머신
macOS, 12코어, 메모리 24GiB
엔티티
필드 12개의 단일 엔티티, 연관관계 없음
데이터
100만 건
측정 방식
모드마다 별도 JVM. 로딩이 끝난 뒤 System.gc()를 3회 호출하고, 그때의 사용 힙에서 로딩 전 값을 뺌

결과힙 점유량, 100만 건

100만 건 전량 조회목록으로 전부 메모리에 올림
100만 건 순회 및 분할 처리Cursor / Scroll / Clear 적용
100만 건 단건 등록 (Insert)persist만 호출

일반 조회, 힙 한도별 결과

✕ 700MBOOM✓ 900MB성공✓ 1GB성공✓ 1.2GB성공✓ 2GB성공✓ 4GB성공

700MB와 900MB 사이는 측정하지 않았다. 성공한 5회 실행의 힙 점유량은 782.9~786.1MB로 일치했다.

문헌과 대조

문헌

영속성 컨텍스트는 관리 엔티티가 차지하는 메모리의 두 배가 필요하다

Vlad Mihalcea, dirty checking 해부 (원문에 측정 수치 없음)
이 측정

건당 786B 대 535B, 약 1.5배

값이 String, BigDecimal, Long인 12필드 엔티티 기준. 다른 필드 구성에서는 측정하지 않았다.

측정하지 않은 것과 한계

  • 연관관계가 있는 엔티티는 측정하지 않았다.
  • Date 같은 가변 타입 필드가 있는 엔티티는 측정하지 않았다.
  • 임베디드 H2만 썼다. MySQL, PostgreSQL 같은 네트워크 DB의 드라이버 버퍼는 측정하지 않았다.
  • G1 외의 GC는 측정하지 않았다.
  • 변경 감지의 CPU 비용은 측정하지 않았다.
  • 대부분 모드당 1회 실행이다. 일반 조회만 힙 한도를 바꿔 5회 실행했다.

재현

java -Ddb=<db경로> -Xmx4g -cp <classpath> bench.Seed 1000000
java -Ddb=<db경로> -Xmx4g -cp <classpath> bench.Load managed
java -Ddb=<db경로> -Xmx64m -cp <classpath> bench.Load scrollClear
java -Ddb=<db경로> -Xmx900m -cp <classpath> bench.Ins noclear 1000000

출처

Hibernate User Guide, Batching (6.4.4)insert 예제의 OOM 설명, flush와 clear, StatelessSession
Hibernate 포럼, StatefulPersistenceContext 메모리loaded state를 유지해야 한다는 메인테이너 설명