JPA를 사용할 때 N+1 문제는 성능상 가장 주의해야하는 부분 중 하나이다. 부서와 사원 같은 1:N 관계의 엔티티 구조에서부서만 먼저 조회한 뒤 나중에 부서에 속한 사원 목록에 접근할 때조회한 부서 수만큼 사원 목록 조회 쿼리가 수행되면서 성능 문제가 발생하는 경우라고 할 수 있다. N+1 번 쿼리가 수행된다고 해서 N+1 문제라고 부른다.1은 처음에 부서 목록 조회한 쿼리, N은 조회한 부서 개수만큼 수행되는 사원 목록 조회 쿼리. 부서 엔티티에서 사원 목록 fetch 설정을 즉시 로딩(EAGER), 지연 로딩(LAZY)으로 하던 모두 발생할 수 있다. 즉시 로딩다음과 같이 EntityManager를 통해 조회하면 즉시 로딩 설정된 사원 목록이 같이 조회되기 때문에 N+1 문제가 발생하지 않는다. ..
분석을 위한 명령어들 모두 JDK 설치되어 있으면 실행을 위해 별도 설치할 것은 없음 스레드 덤프 생성 jstack -l > # jstack -l 3435 > /home/user/jstack.txt 정확한 원인 분석을 원한다면 5초 정도 간격으로 5회 정도 생성 필요 (스레드 상태 변화 확인을 위해) 힙덤프 생성 힙덤프 생성 중 Stop the world 되기 때문에 주의 (시간은 오래걸려도 수초내일 듯하다) jcmd GC.heap_dump # jcmd 3435 GC.heap_dump /home/user/heap_dump.hprof 클래스 로드 현황 확인 명령 실행 시 Stop the world 되기 때문에 주의 jcmd GC.class_stats # -csv=true 옵션을 추가하면 csv형태로 출력 ..
Metaspace란 무엇일까Metaspace는 JDK8 이전의 Perm 영역을 대체하는 것으로 클래스와 메소드의 메타데이터들이 저장되는 영역임Metaspace는 native memory를 사용하기 때문에 힙 영역과는 별개의 영역에 할당됨native memory는 프로세스에 할당되는 메모리 영역으로 C 힙과 스레드 스택도 native memory를 사용함다음 그림을 보면 좀 더 쉽게 이해할 수 있다. 클래스는 최초에 모두 로딩되는 것은 아니고 필요 시점에 로딩되며,클래스가 로딩될 때 Metaspace에 클래스 정보가 저장된다. 소스 코드양이 많아질수록 Metaspace도 그만큼 많이 사용되게 됨보통 클래스 하나당 5~6KB 정도 사용된다고 함그리고 GC 실행 시 저장된 클래스 정보가 unload 될 수도 ..
sun.reflect.GeneratedMethodAccessor 클래스에 대해서톰캣 운영 중에 로딩된 클래스 목록을 확인해보았더니 다음과 같은 클래스들이 굉장히 많이 로드되어있었다. sun.reflect.GeneratedConstructorAccessor54sun.reflect.GeneratedConstructorAccessor57sun.reflect.GeneratedConstructorAccessorXX... 뒤에 숫자는 순차적으로 붙는 것 같은데 이게 확인해보니톰캣 운영 중에 동적으로 생성되어 로드된 클래스였다. 이 클래스들이 Metaspace의 상당히 많은 부분을 차지하고 있었고 무엇인지에 대해 찾아보니 다음과 같았다. JAVA reflection으로 메소드를 호출할 때 기본 최초 15번까지는 JN..