-
JVMBackEnd/자바 2022. 9. 3. 14:07
JVM 은 자바 프로그램과 OS 사이에 위치해 중계자 역할을 한다.
일반 프로그램은 프로그램이 실행되기 위해서 OS가 제어하고 있는 시스템의 RAM을 제어할 수 있어야 한다.
그래서, C같은 언어로 만들어진 프로그램은 이러한 이유 등으로 OS에 종속되어 실행된다.
자바 프로그램은 JVM 에 종속적이다.
OS에 따른 jdk 를 설치하면 해당 OS 에 맞는 JVM 이 설치되고
JVM 은 OS 로부터 메모리를 할당받아 자바 프로그램을 실행한다.
아래는 JVM 구조이다.
RunTime Data Area 는 아래와 같이 여러개의 스레드와 공용 heap, method 공간으로 이뤄져있다.
Method Area는 클래스 로딩이 되는 공간으로 클래스와 인터페이스에 대한 런타임 상수 풀, 멤버 변수(필드), 클래스 변수(Static 변수), 생성자, 메소드가 저장된다.
Runtime Constant Pool 은 각 클래스와 인터페이스의 상수, 메소드와 필드에 대한 모든 레퍼런스를 저장하여 중복을 막는 역할을 수행한다. JVM은 이곳을 통해 해당 메소드나 필드의 실제 메모리상 주소를 찾아 참조한다.
힙 영역은 아래와 같이 또 나뉘는데,
Eden에서 Survivor 로 넘어가는 것을 minor GC, Old 에서 객체가 삭제되는 것은 Major GC 라고 한다.
Permanent 는 생성된 객체 정보의 주소값이 저장되는 공간으로, Class Loader에 의해 로드되는 클래스, 메소드 등에 대한 meta 정보가 저장되는 영역으로 객체의 생명 주기가 같다고 판단되는 객체들이다. 자바의 Class 객체들이나 문자열에 속한 String 객체들이 위치하고 GC대상에서 제외된다.
Old 영역이 꽉차거나 동적으로 생성되는 클래스들이 많아 Permanent에 메모리가 부족해지면 OutOfMemoryError
에러가 발생한다.
Heap size는 JVM에서 자동으로 늘리거나 줄일 수 가 있다. JVM의 기본적인 메모리 설정 방식은 아래와 같다.
JAVA_OPTS="-Djava.awt.headless=true -Dfile.encoding=UTF-8 -server -Xms1024m -Xmx1024m -XX:NewSize=512m -XX:MaxNewSize=512m -XX:PermSize=512m -XX:MaxPermSize=512m -XX:+DisableExplicitGC"
- Xms<size> : Java Heap의 최초 크기(Start Size)를 지정한다.
- Xmx<size> : Java Heap의 최대 크기(Maximum Size)를 지정한다.
Java Heap은 -Xms 옵션으로 지정한 크기로 시작하며 최대 -Xmx옵션으로 지정한 크기만큼 커진다.
Sun HotSpt JVM 계열에서는 최초 크기와 최대 크기를 동일하게 부여할 것을 권장한다. 크기의 동적인 변경에 의한 오버 헤드를 최소화하기 위해서이다. Server 시스템의 경우 항상 최대 사용 메모리로 잡아 놓는 것이 좋다.
메모리가 늘어난다는 것은 부하가 늘어난다는 것이고, 부하가 늘어날때 메모리를 늘리는 작업 자체가 새로운 부하가 될 수 있기 때문에, 같은 값을 사용하는 것이 좋다.
* Xms, Xmx를 동일하게 세팅하는 이유 - Xms로 init 메모리를 잡고, committed 도달할 때까지 Used용량이 점차 증가하는데, committed에 도달시 메모리 추가할당시 시스템 부하발생 (WAS가 몇 ms가량 멈출 가능성 있음) - 메모리 용량은 init < used < committed < max - 보통 운영시스템에서 Xms와 Xmx를 동일하게 지정하는 이유는 init와 max사이에서 used 메모리가 committed까지 사용하게 되면, 신규 메모리 공간을 요구하는데 이 때 약 1초가량 jvm이 메모리 할당 중 멈춰버리는 경우가 있다. 그래서 Xms와 Xmx를 동일하게 주고 메모리를 확보한 상태에서 jvm을 기동시키곤 한다.
-XX:PermSize=<size> : Permanent Generation의 최초 크기를 지정한다.
-XX:MaxPermSize= : Permanent Generation의 최대 크기를 지정한다.
Permanent Generation의 크기가 작아서 Class를 로딩하지 못하면 Out of Memory Error가 발생한다.
PermGen 메모리를 설정하지 않았을경우 디폴트 값은 80MB 정도 이다.
* MaxPermSize는 -Xmx 로 지정한 메모리 용량과 별도로 할당된다.
즉, -Xmx가 256m 이고, -XX:MaxPermSize가 256m 이라면, 최대 512m이 할당될 수 있다는 것이다.
-XX:NewSize<size> : 객체가 생성되어 저장되는 초기공간의 Size로 Eden+Survivor 영역
그리고 New대 Old의 비율은 서버 애플리케이션의 경우 1:2 비율이 가장 적절하다.
JVM 옵션이 다음과 같을 때,
-Xmx1024m –Xms1024m -XX:MaxNewSize=384m -XX:MaxPermSize=128m
*1024MB = 1.024GB
위의 전체 메모리 사용량은 heap 1024m (이 중에서 new가 384m) 그리고 perm이 128m 가 되고,
JVM 자체가 사용하는 메모리가 보통 300~500m 내외가 되서
java process가 사용하는 메모리 량은 대략 1024+128+300~500 = 대략 1.5G 정도가 된다.
* 적정 힙 사이즈 계산방법 Initial heap size of 1/64 of physical memory up to 1Gbyte Maximum heap size of 1/4 of physical memory up to 1Gbyte PC 메모리가 32GB라면 아래와 같이 계산할 수 있다. 초기 메모리 = 32 / 64 = 0.5GB(InititialHeapSize) 최대 메모리 = 32 / 4= 8GB(MaxHeapSize)
https://woooongs.tistory.com/m/86
https://www.holaxprogramming.com/2017/10/09/java-jvm-performance/
https://m.blog.naver.com/pcmola/222074787428
출처: https://epthffh.tistory.com/entry/JVM-메모리-관련-설정 [물고기 개발자의 블로그:티스토리]
https://ifcontinue.tistory.com/m/9
반응형'BackEnd > 자바' 카테고리의 다른 글
GC (0) 2022.09.13 register-based vs stack-based (0) 2022.09.03 리액티브 프로그래밍 - 모던 자바 인 액션 (0) 2022.04.22 CompletableFuture (0) 2022.04.14 코드개선예제 (0) 2022.04.11