JVM (Java Virtual Machine)


자바 가상 머신으로 자바의 바이트코드를 OS에 맞게 해석해주는 역할을 한다.

자바의 바이트 코드는

  1. Java Compiler에 의해서 .java 에서 .class 라는 Java byte code로 변환이 된다.
  2. 기계어가 아니기 때문에 OS에서 바로 실행되지 않고 JVM이 OS에 맞게 해석을 해준다. ( → OS에 상관 없이 실행될 수 있음)

JVM의 구성


Java_jvm

Class Loader

자바 클래스를 JVM에 동적로드하는 자바 런타임 환경 (JRE)의 일부이다. 런타임 시점에 클래스를 로딩하게 해주며 클래스의 인스턴스를 생성하면 클래스 로더를 통해 메모리에 로드한다.

Runtime Data Areas

VM이 프로그램을 수행하기 위해 OS로 부터 별도로 할당 받은 메모리 공간을 말하며, Runtime Data Areas는 크게 5가지 영역으로 나눌 수 있다. Method Area, Heap, Java Virtual Machine Stack, Native Method Stack, PC Register Method Area : 모든 쓰레드가 공유 하는 영역. 클래스, 인터페이스, 메서드, 필드, static 변수등의 바이트 코드를 저장 Heap : 런타임 시 동적으로 할당하여 사용하는 영역. 인스턴스를 생성하면 heap에 저장되게 된다.

자바 7과 자바8 부터의 JVM 차이

  • JDK8 부터 Permanent Heap영역이 제거되고 Metaspace영역이 추가되었다.
  • 기존 Perm은 JVM에 의해 크기가 강제되었던 영역인데, MetaSapce는 Native Memory영역으로 OS가 크기를 조절한다.
  • 얻는 이점은 기존과 비교해 큰 메모리 영역을 사용할 수 있게 되었고, Perm 영역 크기로 인한 OOM을 보기가 힘들어진다.
  • 자바 7 자바 8
    Java_jvm_java7 Java_jvm_java8
    - class, method, static object는 perm 영역에 저장 - class, method는 MetaSpace에 저장
    ^^ - Heap, Perm영역 튜닝 ^^ - static object는 heap에 저장하여 GC의 대상이 될 수 있게함
    ^^ - Perm영역 메모리 옵션 ^^ - heap 튜닝은 JVM, Native영역은 OS가 한다.
    ^^ -XX:PermSize ^^ - MetaSpace영역 메모리 옵션
    ^^ -XX:MaxPermSize ^^ -XX:MetasapceSize
    ^^ ^^ -XX:MaxMetaspaceSize

기타 메모리 옵션..

  • -XX:NewSize : Young Generation의 시작크기
  • -XX:MaxNewSize : Young Generation의 최대크기
  • -XX:NewRatio : Young 과 Old Generation의 비율
  • -Xms : heap 최초 시작 크기
  • -Xmx : heap 최대 크기. 시작과 최대의 값을 동일하게 부여할 것이 권고된다고 함. 크기의 동적인 변경에 의한 오버헤드를 줄이기 위해서라고함.

GC (Garbabe Collection)?


이미 할당된 메모리에서 더 이상 사용하지 않는 메모리를 헤재하는 행동 Young Generation에서 발생하는 GC를 MinorGC라고 하고, 해당 영역에서는 빈번하게 GC가 일어난다. GC가 여러번 일어난 오브젝트는 Old Generation으로 옮겨가게 된다. Old Generation의 메모리도 충분하지 않은 상황이라면 Full GC(Major GC)가 일어나게 되고, 실행중인 스레드를 멈추고 진행하게 된다.

OOM (Out of Memory) ?


java.lang.OutofMemoryError : Java Heap Space → 생성하고자 하는 오브젝트가 JVM Heap메모리 가용영역을 넘가는 경우 java.lang.OutOfMemoryError : GC Overhead Limit Exceeded → GC가 너무 빈번하게 일어나 오버헤드가 결리는 경우로 근본적으로 Heap영역이 부족해서인데, GC가 전체 동작의 98%를 소비했는데도, Heap memory를 2%이하로 확보하였을 경우발생 java.lang.OutOfMemoryError : Metaspace → 익명클래스의 다량 생성 혹은 실제 클래스가 많은데 메모리가 부족할 경우 발생으로 javassist와 같은 동적 클래스 생성을 활용하는 어플리케이션을 긴 시간 동안 사용할 경우 발생할 수 있다.
Execution Engine Load된 Class의 ByteCode를 실행하는 Runtime Module


참고 자료

  • https://medium.com/@lazysoul/jvm-%EC%9D%B4%EB%9E%80-c142b01571f2
  • https://www.nextree.co.kr/p3878/
  • https://johngrib.github.io/wiki/java8-why-permgen-removed/
  • https://coding-start.tistory.com/206
  • https://www.samsungsds.com/kr/insights/1232761_4627.html