자바

JVM (Java Virtual Machine)

ChaeHing 2023. 3. 11. 02:10

JVM (Java Virtual Machine)

  • 자바로 작성한 소스 코드를 해석해 실행하는 별도의 프로그램
  • JVM이 자바 프로그램과 운영체제 사이에서 통역가 역할을 해준다.
    • 프로그램이 운영체제에게 자원을 직접 요청하지 않고 JVM을 통해서 요청하기 때문에 운영체제로 부터 독립적이다.
    • 각 OS별로 JVM이 존재하여 동일한 자바 소스 코드를 OS에 맞게 변환해 실행해 준다.

 

JVM 구조

흐름도

  1. 자바 컴파일러(javac)가 실행되면서 컴파일 진행, 자바 소스 코드(.java) -> 바이트 코드(.class)로 변경
  2. 운영체제로부터 소스코드 실행에 필요한 메모리를 할당 받음 (Runtime Data Area)
  3. 클래스 로더(Class Loder)가 바이트 코드 파일(.class)을 JVM 내부로 불러들여 Runtime Data Area에 적재
    (자바 소스 코드를 메모리에 로드)
  4. 실행 엔진 (Excution Engine)이 런타임 데이터 영역에 적재된 바이트 코드를 실행 - 두가지 방법
    1. 인터프리터(Interpreter)를 통해 코드를 한 줄씩 기계어로 번역하고 실행
    2. JIT compiler를 통해 바이트 코드 전체를 기계어로 번역하고 실행
  5. 기본적으로 인터프리터를 통해 바이트 코드를 실행시키다가, 특정 바이트 코드가 자주 실행 되면 JIT Compiler를 통해 실행

Stack과 Heap

  • JVM에 Java 프로그램이 로드되어 실행될 때 특정 값 및 바이트코드, 객체, 변수등과 같은 데이터들이 메모리에 저장되어야한다.
  • 런타임 데이터 영역이 이러한 정보를 담는 메모리 영역이며 크게 5가지 영역으로 구분되어 있다.

Stack

  • LIFO(Last In First Out)의 자료구조로, 마지막에 저장된 데이터가 제일 먼저 나오는 자료구조
  • 가장 먼저 입력한 데이터를 제일 마지막에 출력
  • 메서드가 호출되면 그 메서드를 위한 공간인 Method Frame이 생성
  • 메서드 내부에서 사용하는 값들인 참조변수, 매개변수, 지역변수, 리턴값, 연산 값들이 임시로 저장
  • Method frame이 Stack에 호출 되는 순서대로 쌓이고, Method의 동작이 완료되면 역순으로 제거

Heap

  • JVM에는 단 하나의 Heap 영역이 존재, JVM 작동시 자동 생성
  • 객체, 인스턴스 변수, 배열이 저장된다.
People people = new People();
  • new 키워드로 Heap메모리영역에 인스턴스가 생성되고 stack 영역의 참조 변수 people가 생성된다.
  • 객체를 다룬다는것은 Stack영역에 있는 참조변수를 통해 Heap 영역에 객체를 다룬다는 뜻
  • Heap영역은 실체 객체의 값이 저장되는 공간

Garbage Collection

  • 메모리를 자동으로 관리하는 프로세스
  • 프로그램에서 더 이상 사용하지 않는 객체를 찾아 삭제하여 메모리를 확보
People people = new People();
people.setName("김덕배"); // setter
people = null;
// 가비지
  • people이라는 참조변수에 People 클래스의 인스턴스 주소값 할당
  • setter로 name이라는 속성 할당
  • people의 null값이 할당되어 "김덕배"라는 name 속성을 가진 인스턴스간의 연결이 끊어짐
  • 해당 인스턴스는 아무도 참조하고 있지 않음
  • 가비지 컬렉터는 이렇게 아무한테도 참조 되고 있지 않은 객체 및 변수들을 검색하여 삭제하여 메모리 공간을 확보

가비지 컬렉션의 동작 방식

  • JVM의 Heap 영역의 객체는 대부분 일회성으로, 메모리에 남아있는 기간이 짧다는 전제로 설계된다.
  • 객체가 얼마나 살아 있냐에 따라서 young영역과 old영역 2가지로 나뉜다.
  • young 영역 : 새롭게 생성된 객체가 할당되고, 많은 객체가 생성되었다가 사라지는것을 반복
    • 해당 영역에서 활동하는 가비지 컬렉터를 Minor GC
  • old 영역 : young영역에서 상태를 유지하고 살아남은 객체들이 복사되는 곳, 보통 young역영보다 크게 할당되고 크기가 큰 만큼 가비자가 적게 발생
    • 해당 영역에서 활동하는 가비지 컬렉터를 Major GC
  • 서로 다른 메모리 구조로 되어있어 세부적인 동작 방식은 다르지만 기본적으로 2가지 단계를 따른다.
    1. Stop The World : 가비지 컬렉션을 실행 시키기 위해 JVM이 애플리케이션의 실행을 멈추는 작업
      • 가비지 컬렉션을 실행하는 스레드외에는 모두 작업중단, 가비지가 정리되면 재개된다.
    2. Mark and Sweep : Mark는 사용되는 메모리와 사용하지 않는 메모리를 식별하는 작업을 의미, Sweep은 Mark단계에서 사용되지 않음으로 식별된 메모리를 해제하는 작업을 의미
  • Stop The World를 통해 모든 작업이 중단되면 가비지 컬렉션이 모든 변수와 객체를 탐색하여 각각 어떤 객체를 참고하는지 확인, 이후 사용되고 있는 메모리를 식별(Mark)하여 사용되지 않는 메모리는 제거(Sweep)