본문 바로가기

IT/JAVA

JVM의 메모리 구조에 대해서

JVM이란

JVM이란 Java Virtual Machine의 약자로,
Java 프로그램을 실행하기 위한 프로그램입니다.

 

JVM은 어느 플랫폼(OS)에서든 Java 프로그램을 사용할 수 있게 해주는 특징을 가지고 있습니다.

즉, Java가 플랫폼에 독립적일 수 있는 이유가 JVM 때문인데, 

일반 애플리케이션 vs Java 애플리케이션

그림과 같이, 일반적으로 하드디스크에서 메모리(RAM)로 데이터를 올릴 때, 운영체제(OS, Operating System)가 관여하게 됩니다. 그래서 일반 애플리케이션OS에 의존적이게 되어 다른 OS에서 사용하려면 같은 코드라도 그 OS에 맞게 변경되어야 합니다.

 

그러나 JVM은 OS에게 메모리를 할당받음으로써 아예 메모리의 일부를 차지해 직접 관리하게 됩니다.

 

Java는 JVM 위에서 JVM과 상호작용을 하면 되기 때문에,

어느 OS던 간에 그에 맞는 JVM이 설치되어 일정 공간을 독립적으로 할당받으면 JVM은 Java 프로그램을 호출하여 실행할 수 있게 되고, 이는 Java를 플랫폼에 독립적일 수 있게 해줍니다.

 

ps. JVM가 할당받는 초기 heap size는 메모리 크기의 1/64입니다.

 

JVM의 구조

Java 실행과정을 통해 JVM의 구조를 살펴보겠습니다. 

Java 실행과정

Runtime Data Area이 바로 JVM이 프로그램을 수행하기 위해 OS로부터 할당받는 메모리 영역입니다.

 

먼저, 개발자가 작성한 java source file (.java 파일)이 자바 컴파일러인 javac에 의해 bytecode로 변환됩니다. (.class 파일)

bytecode로 변환함으로써 JVM이 해석할 수 있게 됩니다.

 

그 다음에, Class Loader에 의해 .class 파일이 메모리에 로드되어 class 객체가 생성됩니다. 

예를들어, 개발자가

Test a = new Test();

라는 코드를 처음 실행하면 JVM은 Test라는 Class를 Class Loader를 통해서 메모리에 로드합니다.

 

하지만 bytecode는 기계어가 아니기 때문에 OS가 해석할 수 없습니다. 

그래서 JVM는 bytecode를 기계어로 변환해줌으로써 OS가 해석할 수 있게 해 줍니다.

 

그러한 역할을 하는 게 Execution Engine입니다.

Execution Engine는 Class Loader에 의해 메모리에 로드된 클래스(bytecode)들을 기계어로 변환해줍니다.

 

기계어로 변환하는 이유는 프로그램은 컴퓨터가 이해할 수 있는 기계어로 번역되어야 컴퓨터 위에서 실행될 수 있기 때문입니다. 

해석된 코드는 RunTime Data Area에서 실질적으로 사용됩니다.

 

JVM 메모리 구조

JVM이 할당받은 메모리인 Runtime Data Area는 어떤 구조를 가지고 있는지 살펴봅시다.

RunTIme Data Area 구조

Method Area: Class Loader에 의해 .class 파일의 정보가 저장되는 곳입니다. JVM이 실행하기 위해선 해당 bytecode들이 메모리 공간에 저장이 되어 있어야 하는데, 이 bytecode들이 Method Area에 올라오게 됩니다.

 

PC register(=Program Counter register): 각 스레드마다 생성됩니다. 스레드란 프로세스 안에서 실행되는 작업 단위를 의미합니다. 레지스터는 현재 수행중인 JVM 명령의 주소값을 저장하게 됩니다.

 

Native Method Stack: 일반적인 메소드를 실행하는 경우 JVM 스택에 쌓이다가 해당 메소드 내부에 Native 방식을 사용하는 메소드가 있다면 해당 메소드는 Native Method Stack에 쌓이게 됩니다.

 

네이티브 방식이란 메모리가 자동으로 관리되지 않는 코드로 구현된 것을 말합니다. (ex) C, C++)

따라서 만약, C++언어로 작성된 메소드가 있다면 해당 메소드는 이 스택에 쌓이게 됩니다.

 

Heap Area: 객체들이 저장되는 곳입니다. java 코드를 작성할 때 new 연산자를 이용해 생성된 객체들이 이 영역에 저장됩니다. 또한 GC(Garbage Collection)가 이 영역에서 이루어집니다.

 

GC는 자동으로 불필요한 메모리를 알아서 정리해주는 기법으로, Java의 특징 중 하나입니다.

 

Stack Area: 각 스레드마다 생성되고, 스택(Stack)엔 프레임(Frame)이 들어가게 됩니다.

프레임이란 메소드가 호출될 때마다 만들어지며, 메소드의 상태 정보를 저장합니다.


따라서 정리하자면

  • JVM은 자바 가상 머신으로, Java 프로그램을 실행하기 위한 프로그램입니다. JVM덕분에 Java 프로그램은 어느 환경에서든지 수정없이 실행할 수 있습니다. (= Java는 플랫폼에 독립적입니다.)
  • JVM은 bytecode를 이해하고, OS와 CPU는 기계어를 이해하기 때문에 컴퓨터에서 Java 프로그램을 실행하기 위해서 javac에 의해 .java 파일이 .class 파일(bytecode)로 변환되고, JVM의 Execution Engine에 의해 .class 파일이  기계어로 변환되는 과정을 거치게 됩니다.
  • RunTime Data Area는 JVM이 OS에게 할당받은 메모리 영역으로, 메모리 구조를 통해 JVM이 어떻게 동작하는지 알 수 있습니다.

 

잘못된 정보가 있다면 피드백 부탁드립니다. 감사합니다 :)