JVM 구조

hyyyynjn·2021년 3월 28일
0

자바 스터디

목록 보기
5/15
post-thumbnail
  • JVM 구조에 대해서 설명하기. 자바 버전에 따라 어떻게 바뀌는지 설명하기

JVM

  • JVM(Java Virtual Machine) : 자바 가상 머신으로 자바 바이트 코드를 실행할 수 있는 주체이다.
    • CPU, OS의 종류와 무관하게 실행이 가능한 특징이 있다.
      • java 바이트코드(.class)는 JVM위에서 작동하고, JVM은 타켓 플랫폼(window, linux등)에 의존한다.
    • JVM은 OS 위에서 동작하는 프로세스로 자바 코드를 컴파일해서 얻은 바이트 코드를 해당 OS가 이해할 수 있는 기계어로 변환하는 역할을 한다.

JVM의 구성 4가지

  1. Class Loader
  2. Execution Engine
  3. Garbage Collector
  4. Runtime Data Area

  • Java Source: 사용자가 작성한 Java 코드
  • Java Compiler: Java Source 파일을 JVM이 해석할 수 있는 Java Byte Code로 변경
  • Class file: Java Compiler에 의해 변환된 Byte Code (.class 파일)
  • Class Loader: JVM 내로 Byte Code를 로딩해 클래스들을 Runtime Data Area에 배치
  • Execution Engine: 로딩된 클래스의 Byte Code를 해석(Interpret)
  • Garbage Collector: Heap 메모리 영역에 적재된 객체 중 참조되지 않은 객체들을 탐색하고 제거
  • Runtime Data Area: JVM이 프로그램을 수행하기 위해 운영체제에서 할당받은 메모리 영역

Class Loader

  • 자바에서 소스코드를 작성하면 .java파일이 생성된다.
  • 자바 컴파일러는 .java 파일을 컴파일하여 .class (바이트코드)파일을 생성한다.
  • Class Loader : 클래스파일(.class)들을 엮어서 Runtime Data Area(JVM이 OS로부터 할당받은 메모리 영역)으로 적재하는 역할을 한다. (자바 애플리케이션이 실행 중일 경우에만 이런 작업이 수행된다.)

Execution Engine

  • Execution Engine : class loader에 의해 메모리영역에 적재된 클래스파일들을 기계어로 변경하여 명령어 단위로 실행하는 역할을 한다.
  • Execution Engine의 두가지 방식
    1. Interpreter 방식
      • 명령어를 하나하나 실행하는 방식이다.
    2. Just-In-Time 컴파일러 방식
      • Just-In-Time 컴파일러에 의해 적절한 시간에 전체 바이트 코드를 네이티브 코드로 컴파일한다.
      • Execution Engine이 네이티브로 컴파일된 코드를 실행하는 방식이다. (성능을 높이는 방식)

Garbage Collector

  • Garbage Collector(GC) : Heap 메모리 영역에 적재된 객체들 중에서 참조되지 않은 객체들을 탐색 후 제거 하는 역할을 한다.
    • GC가 역할을 하는 시간은 정확하게 모른다.
    • GC가 수행되는 동안 GC를 수행하는 thread를 제외한 모든 thread가 일시정지된다.
      • Full GC가 일어나면 수 초간 모든 thread가 정지하여 장애로 이어지는 문제가 생길 수 있다.

Runtime Data Area

  • Runtime Data Area : JVM의 메모리 영역이다. 자바 애플리케이션을 실행할 때 사용되는 데이터들을 적재하는 영역이다.
    • Runtime Data Area 영역은 크게 5가지로 나뉜다.
      1. Method Area
      2. Heap Area
      3. Stack Area
      4. PC Register
      5. Native Method Stack
    • thread 공유 영역 : Method Area, Heap Area
    • thread 고유의 영역 : Stack Area, PC Register, Native Method Stack

  • Method 영역: 클래스, 변수, Method, static 변수, 상수 정보 등이 저장되는 영역(모든 Thread가 공유)
  • Heap 영역: new 명령어로 생성된 인스턴스와 객체가 저장되는 영역(모든 Thread가 공유)
  • Stack 영역: Method 내에 사용되는 값이 저장되는 영역, 메소드가 호출될 때 적재되고, 실행이 완료되면 LIFO로 삭제(각 Thread별로 생성)
  • PC Register: 현재 수행중인 JVM 명령의 주소값 저장(각 Thread별로 생성)
  • Native Method Stack: 다른 언어(C/C++ 등)의 메소드 호출을 위해 할당되는 영역, 언어에 맞게 Stack이 생성됨

Method Area(메소드 영역)

  • 필드 정보 : 클래스 멤버 변수 이름, 데이터 타입, 접근 제어자
  • 메소드 정보 : 메소드 이름, 리턴 타입, 파라미터, 접근제어자 정보
  • Type 정보 : interface인지, class인지
  • Constant Pool(상수 풀) : 문자 상수, 타입, 필드 ,객체 참조가 저장됨
  • static 변수, final class 변수
    가 생성되는 영역이다.

Heap Area(힙 영역)

  • new 키워드로 생성된 객체와 배열이 생성되는 영역이다.
    • Method Area에 로드된 클래스만 생성이 가능하고
    • Garbage Collector(GC)가 참조되지 않은 메모리를 확인하고 제거하는 영역이다.

Stack Area(스택 영역)

  • 지역변수, 파라미터, 리턴 값, 연산에 사용되는 임시 값 등이 생성되는 영역이다.
    • int a = 10;
      • 정수값이 할당 될 수 있도록 메모리공간을 a라고 잡아두고, 그 메모리 영역에 10의 값이 들어간다.
      • 다시 말하면, Stack Area에 a라는 이름의, 값이 10인 메모리 공간을 만든다.
    • Person p = new Person();
      • Person p는 Stack Area에 생성되고, new로 생성된 Person 크래스의 인스턴스는 Heap Area에 생성된다.
        • Stack Area의 p가 Heap Area에 생성된 객체를 가리키고(참조하고)있다.
  • 메소드를 호출할 때마다 개별적으로 Stack이 생성된다.

PC Register(PC 레지스터)

  • Thread가 생성될 때마다 생성되는 영역으로 Program Counter(PC : 현재 thread가 실행되는 부분의 주소와 명령을 가리키는 포인터)를 저장하는 영역이다.
  • PC Register를 이용하여 thread를 돌아가면서 수행할 수 있게 한다.

Native Method Stack

  • Java 외의 언어로 작성된 네이티브 코드를 위한 메모리 영역이다.
    • 보통 C/C++등의 코드를 수행하기 위한 스택이다.

Heap Area & Garbage Collector

Heap Area

  • heap 영역은 GC의 주요 대상이다.
  • heap 영역은 5개의 영역으로 나뉜다.
    1. Eden
    2. Survivor1
    3. Survivor2
    4. Old
    5. Permanent (JDK7까지 heap영역에 permanent가 존재했다. JDK8 이후부터 사라지고 일부가 meta space 영역(Native Stack 영역의 일부)으로 변경됨)

  • heap 영역으로 5개로 나눈 이유 : 효율적으로 GC가 일어나게 하기 위해서이다.

Garbage Collector

  • Garbage : 정리되지 않은 메모리, 유효하지 않은 메모리 주소를 의미한다.
String[] array = new String[2];

array[0] = '0';
array[1] = '1';

array = new String[] {'G', 'C'};
  • 위 코드에서 String 배열이 할당 되기 전 array[0] = '0';array[1] = '1';에 해당하는 0과 1은 주소를 잃어버려서 사용할 수 없는 메모리가 된다. 이를 자바에서 Garbage라고 부른다.

  • 또한 앞으로 사용하지 않고 메모리를 가지고 있는 객체 역시 Garbage에 포함된다.

  • GC는 Minor GC, Major GC로 나뉜다.

Minor Garbage Collector

  • Young 영역(Eden, Survivor1, Survivor2) 에서 일어나는 GC이다.
  1. 객체가 최초로 생성되는 영역은 Eden영역이다.
  2. Eden영역에 객체가 가득차면 첫번째 GC가 일어난다.
  3. Survivor1영역에 Eden 영역의 메모리를 그대로 복사한다. 그리고 Survivor1 영역 이외의 다른 영역의 객체를 제거한다.
  4. Eden영역, Survivor1영역도 가득차게 되면, 이 두 영역에 생성된 객체들 중에서 참조되고 있는 객체가 있는지 검사한다.
  5. Eden영역, Survivor1영역에 생성된 객체들 중 참조되고 있는 객체들만 Survivor2 영역에 복사한다.
  6. Survivor2 영역을 제외한 다른 영역들의 객체를 제거한다.
  7. 위의 과정중에서 일정 횟수 이상 참조되는 객체들을 Survivor2 영역에서 Old 영역으로 이동시킨다.
  • 이 과정을 계속 반복한다.
    • Survivor2 영역이 가득 차기 전에 Old 영역으로 이동시켜 비운다.

Major Garbage Collector (Full GC)

  • Old 영역에서 일어나는 GC이다.

    1. Old 영역에 있는 모든 객체들을 검사하며 참조되고 있는지 확인한다.
    2. 참조되지 않은 객체들을 한번에 모아서 제거한다.
  • Minor GC보다 시간이 훨씬 많이 걸린다.

  • 실행중에 GC를 제외한 모든 thread가 중지된다.

  • Old영역에 있고 참조되지 않은 객체들을 표시하고, 해당 객체들을 모두 제거한다.

    • 이때, Heap 메모리 영역 중간에 빈 메모리 공간이 생기는데, 이를 없애기 위해 메모리를 재구성한다.
    • 이 과정에서 다른 쓰레드가 메모리를 사용하면 안되기 때문에 모든 쓰레드가 정지하게 된다.

0개의 댓글