Java

JVM 메모리 구조 (JAVA)

devJK93 2024. 2. 8.

JVM과 JVM 메모리 구조

 

 

  JVM 메모리 구조를 알아야 하는 이유

 

대규모 프로젝트를 Java 개발할 , 메모리 관리에 따라 프로그램 성능 월등히 차이날 있기 때문입니다.

이것이 어떤 상황을 의미하는지, 메모리 구조를 잘 알고 있다면 어떻게 프로그램 성능 개선에 활용할 수 있는지 아직 알 수 없지만

자바 개발자라면 기본적으로 알고 있어야 하는 덕목인 것 같아서 정리하는 시간을 가져봅니다.

 

우선 JVM이 무엇인지 알아보겠습니다.

 

  JVM이란?

 

JVM Java Virtual Machine, 자바 가상 머신

  • 자바와 운영체제사이에서 중계자 역할을 합니다.
  • 그래서 자바가 운영체제 종류에 영향받지 않고 돌아갈 수 있습니다.
  • 메모리 관리를 자동으로 해주는 가비지 컬렉터(GC)의 기능도 있습니다.
  •  외의 기능들..

JVM 덕에 운영체제와 플랫폼에 구애받지 않고 독립적으로 Java 애플리케이션이 실행 있는 것입니다.

 

그림을 통해 Java 애플리케이션의 실행단계를 알아보겠습니다.

 

JAVAC compiler & JVM & OS

 

  1. 자바 코드(자바 파일) 컴파일러 의해 바이트 코드(클래스 파일) 변환됩니다.
  2. JVM 바이트 코드를 읽은 다음 운영체제에 적합한 기계어로 바꿔서 실행시켜 줍니다.

즉, Java 운영체제와 플랫폼에 종속되지 않습니다.

JVM 운영체제와 플랫폼에 종속될 뿐입니다.

우리는 해당 운영체제와 플랫폼에 적합한 JVM 설치하기만 하면 됩니다.

 

  JVM 메모리 구조

 

JVM 구조는 크게 보면,

Class Loader, Execution Engine, Garbage Collector, Runtime Data Area, 4가지로 나눌 있습니다.

 

JVM structure

 

자바 소스 파일은 자바 컴파일러에 의해서 바이트 코드 형태인 클래스 파일이 됩니다.
클래스 파일은 그림처럼 클래스 로더가 읽어들이면서 JVM 수행됩니다.

 

(1) Class Loader

  • JVM 내로 클래스 파일을 로드하고, 링크를 통해 배치하는 작업을 수행하는 모듈입니다. 
  • javac(자바 컴파일러) 의해 생성된 클래스파일들을 엮어서 JVM 운영체제로부터 할당받은 메모리영역인 Runtime Data Area 적재하는 역할 Class Loader 합니다. (자바 애플리케이션 런타임시에 수행됩니다.)

(2) Execution Engine

  • 클래스 로더를 통해 JVM 내의 Runtime Data Area에 배치된 바이트 코드들을 기계어로 변경해서 명령어 단위로 읽어서 실행합니다.
  • 최초 JVM이 나왔을 당시에는 인터프리터 방식이었기때문에 속도가 느리다는 단점이 있었지만 JIT 컴파일러 방식을 통해 이 점을 보완하였습니다.
  • JIT는 바이트 코드를 어셈블러 같은 네이티브 코드로 바꿈으로써 실행이 빠르지만 역시 변환하는데 비용이 발생하였습니다.
  • 이 같은 이유로 JVM은 모든 코드를 JIT 컴파일러 방식으로 실행하지 않고, 인터프리터 방식을 사용하다가 일정한 기준이 넘어가면 JIT 컴파일러 방식으로 실행합니다.

(3) Garbage Collector

  • Garbage Collector(GC)는 힙 메모리 영역에 생성된 객체들 중에서 참조되지 않은 객체들을 탐색 후 제거하는 역할을 합니다. 이때, GC가 역할을 하는 시간은 언제인지 정확히 알 수 없습니다.
  • 또 다른 특징은 GC가 수행되는 동안 GC를 수행하는 쓰레드가 아닌 다른 모든 쓰레드가 일시정지된다는 점인데
  • 특히 Full GC가 일어나서 수 초간 모든 쓰레드가 정지한다면 장애로 이어지는 치명적인 문제가 생길 수 있는 것입니다. 

(4) Runtime Data Area

  • JVM 메모리 영역으로 자바 애플리케이션을 실행할 사용되는 데이터들을 적재하는 영역입니다. 영역은 크게 Method Area, Heap Area, Stack Area, PC Register, Native Method Stack 나눌 있습니다.

runtime data area

 

1. Method area (메소드 영역) - 클래스, 정적인 정보, 상수..

 

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

 

2. Heap area (힙 영역) - 객체

 

new 키워드로 생성된 객체와 배열이 생성되는 영역입니다.

메소드 영역에 로드된 클래스만 생성이 가능하고 Garbage Collector가 참조되지 않는 메모리를 확인하고 제거하는 영역입니다.

힙 영역은 다시 5개의 영역으로 나뉠 수 있습니다.

heap area

 

3. Stack area (스택 영역) - 지역변수

 

지역 변수, 파라미터, 리턴 값, 연산에 사용되는 임시 값등이 생성되는 영역입니다.

int a = 10; 이라는 소스를 작성했다면 정수값이 할당될 수 있는 메모리공간을 a라고 잡아두고 그 메모리 영역에 값이 10이 들어가게 됩니다. 즉, 스택에 메모리에 이름이 a라고 붙여주고 값이 10인 메모리 공간을 만드는 것입니다.

클래스 Person p = new Person(); 이라는 소스를 작성했다면 Person p는 스택 영역에 생성되고 new로 생성된 Person 클래스의 인스턴스는 힙 영역에 생성됩니다.

그리고 스택영역에 생성된 p의 값으로 힙 영역의 주소값을 가지고 있게 됩니다.. 즉, 스택 영역에 생성된 p가 힙 영역에 생성된 객체를 가리키고(참조하고) 있는 것입니다.

메소드를 호출할 때마다 개별적으로 스택이 생성됩니다.

stack area

 

4. PC Register (PC 레지스터)

Thread(쓰레드)가 생성될 때마다 생성되는 영역으로 Program Counter 즉, 현재 쓰레드가 실행되는 부분의 주소와 명령을 저장하고 있는 영역입니다. (*CPU의 레지스터와 다름)

이것을 이용해서 쓰레드를 돌아가면서 수행할 수 있게 합니다.

 

5. Native method stack

자바 외 언어로 작성된 네이티브 코드를 위한 메모리 영역입니다.

보통 C/C++등의 코드를 수행하기 위한 스택입니다. (JNI)

 

  정리

 

JVM에 대해 다시 한번 정리하면서 자바 프로그램 실행과정과 JVM 메모리 구조를 대략적으로 알 수 있었다.

데이터들을 적재하는 영역인 Runtime Data Area를 구성하는 영역들과 그 영역들에 저장되는 데이터 종류들에 대해 잘 숙지해두어야 다음 이론 학습에 도움이 될 것 같은 느낌

 

 

참고 자료들

 

블로그 :

[느리더라도 꾸준하게](https://steady-coding.tistory.com/305)
[기본기를 쌓는 정아마추어 블로그](https://jeong-pro.tistory.com/)
[Limky 삽질 블로그](https://limkydev.tistory.com/51)
[Develog](https://asfirstalways.tistory.com/158)

'Java' 카테고리의 다른 글

[Java] JDK, JRE, JVM 질의응답 (ChatGPT)  (1) 2024.08.31
[Java] Reflection  (2) 2024.02.21
Generics (Java)  (1) 2024.02.12

댓글