글 검색

공개된 글의 제목과 본문을 검색합니다.

    닫기 Esc

    1. JVM이란?#

    • JVM - Java Virtual Machine
      • Virtual의 의미
        • JVM은 물리적인 형태가 아닌 소프트웨어로서 하나의 개념으로 존재한다.
      • Machine의 의미
        • JVM은 독자적으로 작동할 수 있는 메커니즘과 구조를 가지고 있다.
        • 하나의 v축약된 컴퓨터와 같은 의미다.
    • JVM이 구체적으로 무엇이냐는 질문에 정확한 정의를 내린다기 보다는 하나의 개념, 스펙에 지나지 않는다.
      • 어느 누구도 정확하고 자세한 설계도를 제공하지 않는다.
      • 표준화된 정의만이 존재할 뿐이다.
      • 각 JVM 벤더들은 표준에 맞도록 자신의 JVM을 별도로 구현한다.
    • 즉 JVM은 정의된 스펙을 구현한 하나의 독자적인 프로세스 형태로 구동되는 Runtime Instance라고 할 수 있다.
    그림1
    그림1
    • Class Loader
      • JVM 내로 class파일들을 Load 하여 Loading된 클래스들을 Runtime Data Area에 배치
    • Execution Engine
      • Loading된 클래스의 Bytecode를 해석
    • Runtime Data Areas
      • JVM이라는 프로세스가 프로그램을 수행하기 위해 OS에서 할당받은 메모리 공간

    JVM 아키텍처#

    • Method Area
      • 클래스, 변수, 메소드, static 변수, 상수 정보 등이 저장되는 영역
    • Heap Area
      • new 명령어로 생성된 인스턴스와 객체가 저장되는 구역
    • Stack Area
      • Method 내에서 사용되는 값들(매개변수, 지역변수, 리턴값 등)이 저장되는 구역
      • 메소드 호출시마다 메모리에 LIFO로 생성/삭제된다.
    • PC Register
      • PC 레지스터와 역할이 비슷하고, JVM 명령의 주소값이 저장된다.
    • Native Method Stack
      • 다른 언어(C/C++ 등)의 메소드 호출을 위해 할당되는 구역으로 얼어에 맞게 Stack이 형성되는 구조

    1.2 Java Heap#

    • Java의 Heap영역은 메모리 자동해제, 즉 GC(Garbege Collection)과 연관이 깊다.
    • 사람들이 자바의 메모리 구조는 곧 Heap이라 오해하지만, 여러 다른 메모리 영역도 존재한다.
    • Heap은 Instance와 Array객체 두 가지 종류만 저장되는 공간일 뿐이다.
    • Heap은 데이터가 공유되어 동기화 문제 이슈가 발생할 수 있다.
    • JVM은 Heap에 Memory를 할당하는 Instruction만 존재하고 메모리 해제를 위한 어던 Java Code나 Bytecode도 존재하지 않는다.
    • 메모리 해제는 오직 GC를 통해서만 수행된다.
      • 이 또한 정해진 부분 없이 벤더마다 다를 수 있다.

    1.2.1 Hotspot JVM의 Heap 구조#

    • Young Generation은 Eden과 Survivor영역으로 구성된다.
      • 이 영역에서 일어나는 GC를 Minor GC라 말한다.
      • Eden은 최초로 메모리에 할당되는 장소이며 꽉 차게 되면 참조 여부를 체크해 Live Object라면 Survivor영역으로 넘어가고 아니라면 GC에 의해 메모리에서 해제된다.
      • Survivor영역은 말 그대로 살아남은 Object들이 잠시 머무르는 장소로 2개의 영역이 있지만 하나의 영역만을 사용한다.
    • Young Generation에서 오래 살아남은 객체는 Old Generation으로 이동된다.
      • 이 영역에서 일어나는 GC를 Full GC라고 한다.
      • 특정 회수 이상 참조되어 Age를 초과한 Object를 의미한다.
    • Perm 영역은 보통 Class의 Meta 정보나 Method의 Meta 정보, Static 변수와 상수 정보 등이 저장되는 공간으로 흔히 메타데이터 저장 영역이라고도 한다.
    • 자바 8에서 JVM 메모리 구조적 개선사항으로 Perm 영역이 Metaspace영역으로 전환되어 Perm 영역은 사라지게 되었다.
      • 해당 Metaspace 영역은 Native 메모리에서 관리된다.

    1.2.2 Java 8의 Metaspace 초기치와 최대치 확인#

    shell
    ./java -XX:+PrintFlagsFinal -version -server | grep MetaspaceSize
    • 위 명령어를 실행하면 7버전의 경우 82MB, 8버전의 경우 16Exabyte라는 매우 큰 수치를 볼 수 있다.
      • 16ExaByte는 64Bit 프로세서가 취급할 수 있는 메모리 상한치다.
    • Metaspace 영역은 Native 메모리로 다루기 때문에 프로세스가 이용할 수 있는 메모리 자원을 최대한 활용할 수 잇다고 본다.
      • 그러나 이 메모리 크기도 별도의 옵션(MaxMetaspaceSize)을 통해 제한이 가능한다.
      • Classloader에 메모리 누수가 의심될 경우 -XX:MaxMetaspaceSize를 지정할 필요가 있다고 본다.
    • Metaspace는 만능의 영역이 아니기 때문에 기존 발생한 메모리 누수가 완벽하게 해소되지는 않는 것으로 보인다.
      • 기존엔 메모리 누수가 의심되는 환경에서 Perm 영역의 상한값이 모종의 제한 역할을 했다.
      • Metaspace 영역에서는 기본적으로 이 제한의 역할이 존재하지 않기 대문에 무한하게 메모리 영역이 확대될 수 있다.
    • Metaspace는 필요에 따라 자동적으로 메모리 상한치가 증가하기 때문에 일반적으로 크게 주의를 가지고 설정할 필요가 없다.

    1.2.3 IBM JVM의 Heap 구조#

    IBM JVM의 Heap은 Java 1.4.X 이전과 Java 5 이후를 기준으로 달라진 부분이 있다.

    • 1.4.2 까지는 System Heap과 Heap으로 구분되었으나 5부터는 이러한 구분이 사라졌다.
    • 5부터는 GC의 설정에 따라 Generational Heap 구성이 가능해졌다.
    • 5에 와서 IBM JVM의 Heap에서는 두 가지의 큰 변화가 있었다.
      • System Heap을 더 이상 포함하지 않게 된 것
      • Hotspot JVM과 같이 Generational Heap을 사용할 수 있게 된 것
    • GC옵션 중 Genetation Concurrent 옵션인 `-Xgcpolicy:gencon을 추가하고 JVM을 시작하면 아래 그림과 같은 형태의 Heap이 구성된다.
    • Hotspot JVM의 Young Generation역할을 하는게 Nursery Genetation이다.
      • Object가 생성된지 얼마 되지 않아 Garbege가 되어 사라지는 것을 흔히 유아 사망률(Infant Mortality)이라 한다.
      • 이에 착안해 탁아소라는 명칭을 사용한듯 하다.
    • Nursery도 Allocate와 Survior 영역으로 나뉘게 된다.
      • Allocate는 Object가 최초로 할당되는 곳이다.
      • Survior은 Allocate 영역이 꽉 차거나 다른 이유로 인해 Allocate Failure이 발생하게 되면 Allocate영역의 Live Object를 대피시키는 곳이다.
      • 이 또한 GC의 과정이다.
    • Tenured 영역은 Nursery영역의 성숙한 Object들을 Promotion하는 곳이다.
    전체 글 둘러보기