JVM (Java Virtual Machine)

Fox·2023년 12월 19일
0
post-thumbnail

JVM이란?

정의

자바 가상 머신(Java Virtual Machine)의 줄임말이다.

  • OS와 Java 어플리케이션 사이에서 자바코드를 실행할 수 있는 환경을 제공해 준다.
  • 각 운영체제에 맞도록 실행파일을 새로 만들어 주어야 하지만 OS에 구애받지 않고 JAVA 어플리케이션을 실행할 수 있다.
  • 가장 중요한 메모리 관리, GC(Garbage Collection)을 수행한다.

즉, OS에 종속받지 않고 CPU가 Java를 인식, 실행할 수 있게 하는 가상 컴퓨터이다.

JVM의 구조는 크게 아래와 같이 나눠진다.
1. Class Loader
2. Execution Engine
3. Interpreter
4. JIT Compiler (Just In Time Compiler)
5. GC
6. Runtime Data Areas


JVM의 구성


클래스 로더(Class Loader)

정의

클래스를 처음으로 참조할 때 클래스를 로드하고 링크하는 역할을 한다.
Runtime 시점에 클래스를 로딩하게 해 주며 클래스의 인스턴스를 생성하면 클래스 로더를 통해 메모리에 로드한다.

실행 엔진(Execution Engine)

정의

자바 바이트 코드(.class)는 기계가 바로 수행할 수 있는 언어가 아니라 인간이 비교적 보기 편한 형태로 기술된 것이다.
그래서 실행 엔진은 이와 같은 바이트 코드를 JVM 내부에서 기계가 실행할 수 있는 형태로 변경한다.

인터프리터(Interpreter)

정의

자바는 인터프리터 방식을 사용하여 자바 바이트 코드를 명령어 단위로 읽어서 실행한다.
원시 코드를 기계어로 번역하는 컴파일러와 다르게 프로그래밍 언어의 소스코드를 바로 실행하는 프로그램이다.
하지만 한 줄씩 수행하기 때문에 수행 속도가 느리다는 단점이 있다.

JIT Compiler (Just In Time Compiler)

정의

인터프리터의 단점을 보완하기 위해 JIT 컴파일러가 도입되었다.
JIT 컴파일러는 바이트코드를 컴파일하여 native code(네이티브 코드)로 변환하여 사용한다.
즉, 한 번 컴파일된 코드는 빠르게 수행하게 되어 수행 속도가 빠르게 된다.
하지만 컴파일하는 과정에서 비용이 들기 때문에, 한 번만 수행할 코드라면 인터프리터를 사용하는 것이 유리하다.

런타임 데이터 영역(RunTime Data Areas)

정의

프로그램을 수행하기 위해 OS에서 할당받은 메모리 공간이며 크게 5가지 영역으로 나눌 수 있다.

1. PC Register

  • PC Register는 각 스레드 별로 하나씩 존재한다.
  • 스레드가 어떤 명령을 실행할지 기록하는 부분이다.

2. JVM Stack

  • 메서드의 매개변수, 지역변수, return주소, 임시변수 등의 정보를 기록하는 스택이다.
  • 각 스레드 별로 생성되기 때문에 다른 스레드는 접근할 수 없다.
  • 메서드 호출이 종료되면 스택에서 정보들이 제거된다.

3. Native Method Stack

  • 자바 외의 언어로 작성된 네이티브 코드들을 위한 스택이다.
  • Java Native Interface를 통해 호출되는 C/C++ 등의 코드를 수행한다.

4. Method Area

  • 모든 스레드가 공유하는 메모리 영역이다.
  • 클래스, 인터페이스, 메서드, 필드, Static변수 등의 바이트 코드를 보관한다.
  • Runtime Constant Pool이라는 별도의 관리영역으로 중복을 막는 역할을 수행한다.

5. Heap

  • Runtime 시점에 동적으로 할당하여 사용하는 영역이다.
  • 클래스를 이용해 인스턴스를 생성하면 Heap에 저장된다.(new연산자를 이용해 생성된 객체를 저장하는 곳)
  • Heap은 크게 New/Young, Old, Permanent Generation 3 영역으로 나뉜다.



가비지컬렉터(GC)

정의

  • 자바 애플리케이션에서 사용하지 않는 메모리를 자동으로 수거하는 기능을 말한다.
  • 자바에서는 크게 Young, Old영역으로 구분하는데 새롭게 생성하는 객체는 Young, 오랫동안 살아남은 객체는 Old라고 표현한다.
  • 접근할 수 없는 객체는 제거(Sweep) 대상이 되고, 해당 객체들을 제거하며 메모리 영역 중에서 필요 없게 된 영역을 관리해 준다.

가비지 컬렉터와 컬렉션의 차이

  • 가비지 컬렉터 : 메모리 관리를 담당하는 시스템 또는 프로그램의 구성 요소이며, 메모리에서 더 이상 사용되지 않는 객체를 찾아 제거하여 메모리를 회수하는 역할을 수행한다.
  • 가비지 컬렉션 : 메모리 관리 기술 중 하나로, 가비지 컬렉터에 의해 수행되는 프로세스를 의미.

가비지 컬렉션은 프로세스 자체를 얘기하고 컬렉터는 실제 역할을 수행하는 주체를 얘기한다.

Young Generation(Young 영역)이란?

  • 새롭게 생성된 객체가 할당(Allocation)되는 영역
  • 대부분 객체가 금방 연결할 수 없는 Unreachable 상태가 되기 때문에, 많은 객체가 Young 영역에 생성되었다가 사라진다.
  • Young 영역에 대한 가비지 컬렉션(Garbage Collection)을 Minor GC라고 부른다.

Old Generation(Old 영역)이란?

  • Young 영역에서 Reachable 상태를 유지하여 살아남은 객체가 복사되는 영역
  • Young 영역보다 크게 할당되며, 영역의 크기가 큰 만큼 가비지는 적게 발생한다.
  • Old 영역에 대한 가비지 컬렉션을 Major GC 또는 Full GC라고 부른다.

Permanent Generation(Perm 영역)이란?

  • JVM에서 클래스 메타데이터(클래스와 메서드, 필드 등의 정보)를 저장하는 곳
  • 클래스 로더는 클래스 파일을 읽어 들여서 이 영역에 클래스 메타데이터를 저장한다.
  • 이 정보들은 JVM 실행 도중에 변경되지 않으며, JVM 종료 시까지 유지된다.

자바 8 버전 이후에는 metaspace 영역으로 대체되었다.

Metasapace 영역이란?

  • Perm 영역에서 저장하던 Class의 Meta 정보들이 이 영역에 저장된다.
  • Native Memory 영역에 위치하며, JVM이 아닌 OS 레벨에서 관리된다.
  • 클래스 메타데이터와 리플렉션을 사용하는 애플리케이션에서 사용하는 일부 메모리를 저장한다.

대체된 이유는?

  • Perm 영역의 메모리 누수, OutOfMemoryError 등과 같은 문제
    • 클래스 로딩 및 언로딩 과정에서 메모리 할당 및 해제의 빈번한 발생으로 인해 이러한 문제가 더 심각해졌다.
  • 클래스 메타데이터를 Native Memory에 저장하면서, JVM에서의 OutOfMemoryError 문제가 해결되었다.


JVM 자바 프로그램 실행과정

  1. 자바 프로그램이 실행되면 JVM은 OS로부터 프로그램 실행에 필요한 메모리를 할당받는다. JVM은 이 메모리를 용도에 따라 여러 영역으로 나누어 관리한다.
  2. 자바 컴파일러(javac)가 자바 소스코드(.java)를 읽어 들여 자바 바이트코드(.class)로 변환시킨다.
  3. 클래스 로더(Class Loader)를 통해 클래스 파일(.class)을 JVM으로 로딩한다.
  4. 로딩된 클래스 파일은 실행 엔진(Execution Engine)을 통해 해석된다.
  5. 해석된 바이트코드는 Runtime Data Area에 배치되어 실질적인 수행이 이루어진다.
  6. 위 실행과정 속에서 JVM은 필요에 따라 스레드 동기화(Thread Synchronization)와 GC 같은 작업을 수행한다.












참고 : https://code-lab1.tistory.com/92
참고 : https://velog.io/@yarogono/Java%EA%B0%80%EB%B9%84%EC%A7%80-%EC%BB%AC%EB%A0%89%ED%84%B0Garbage-Collector%EB%9E%80

profile
주니어개발자 Fox 입니다 🦊

0개의 댓글