JVM과 구조

이건희·2023년 3월 26일
1

JVM(Java Virtual Machine)

지난 스터디 발표에서 효준이가 발표한 JVM에 대해 흥미가 생겨 한번 더 찾아보게 되었다.
우선 JVM이란 무엇일까?

  • 자바 가상 머신으로 자바 바이트 코드를 실행할 수 있는 주체다.
  • CPU나 운영체제(플랫폼)의 종류와 무관하게 실행이 가능하다.
  • 즉, 운영체제 위에서 동작하는 프로세스자바 코드를 컴파일해서 얻은 바이트 코드를 해당 운영체제가 이해할 수 있는 기계어로 바꿔 실행시켜주는 역할을 한다.
  • JVM의 구성을 살펴보면 크게 4가지(Class Loader, Execution Engine, Garbage Collector, Runtime Data Area)로 나뉜다.

1. Class Loader

자바에서 소스를 작성하면 Person.java 처럼 .java파일이 생성된다.
java 소스를 자바 컴파일러가 컴파일하면 Person.class 같은 .class파일(바이트코드)이 생성된다.
이렇게 생성된 클래스파일들을 엮어서 JVM이 운영체제로부터 할당받은 메모리영역인 Runtime Data Area로 적재하는 역할을 Class Loader가 한다. (자바 애플리케이션이 실행중일 때 이런 작업이 수행된다.)

2. Execution Engine

Class Loader에 의해 메모리에 적재된 클래스(바이트 코드)들을 기계어로 변경해 명령어 단위로 실행하는 역할을 한다.
명령어를 하나 하나 실행하는 인터프리터(Interpreter)방식이 있고 JIT(Just-In-Time) 컴파일러를 이용하는 방식이 있다.

여기서 컴파일 방식에 대해 알아보자. 컴파일 방식에는 크게 두가지 방식이 있다.

  • 컴파일 방식 : 프로그램 전체를 한번에 기계어로 변역한 후 링킹 작업을 거쳐 컴퓨터에서 실행 가능한 실행 프로그램을 만듦
  • 인터프리터 방식 : 한줄씩 기계어로 번역한 후 즉시 실행하는 방식

자바는 두가지의 방식을 사용한다.

  • JIT 컴파일러
  • JIT 컴파일러는 한번 읽어서 번역한 코드는 다시 번역하지 않는다. 한번 번역한 코드를 저장소에 저장시킨다.
  • 즉 반복되는 코드를 모두 컴파일러로 컴파일 시킨다. 그래서 인터프리터가 한줄 한줄씩 읽을 때 보조를 한다.
  • 인터프리터는 반복되는 코드를 JIT 컴파일러가 이미 컴파일해 저장해 놓았으므로 바로바로 사용할 수 있다.

3. Garbage Collector

Garbage Collector(GC)는 Heap 메모리 영역에 생성(적재)된 객체들 중에 참조되지 않는 객체들을 탐색 후 제거하는 역할을 한다.
GC가 역할을 하는 시간은 정확히 언제인지를 알 수 없다.
GC가 실행 되는 동안은 다른 쓰레드는 모두 일시정지 된다. 따라서 GC가 실행 돼 모든 쓰레드가 정지한다면 장애로 이어질 수도 있다.

4. Runtime Data Area

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

Runtime Data Area의 구조

4.1 Method area(메소드 영역)

클래스 파일의 정보와 클래스(Static) 변수, 메서드 정보, 생성자, 상수(Final) 등을 저장하는 곳이다. 이러한 정보는 JVM이 실행될 때 클래스 로더에 의해 로드되어 Method Area에 저장된다.
Method area 는 클래스가 로드 될 때 초기화되며, JVM이 종료 될때까지 유지된다. 따라서 JVM이 오래 사용되면 OutOfMemoryError가 발생할 수 있다.

좋은 그림이 있어 가지고 와 보았다.

  • 위 그림에서 지역 변수, 클래스 등은 아직 실행되지 않아 Heap, Stack 영역에는 비어 있다고 가정
  • Static 변수와 메소드는 무조건 Method 영역에 적재
  • 일반 인스턴스 변수인 Counter Class의 변수 State, 그리고 count는 final 키워드가 붙었음에도 Method 영역에 들어가지 않는다. (Heap에 들어감)

4.2 Heap area (힙 영역)

new 키워드로 생성된 객체와 배열이 생성되는 영역이다(동적으로 할당되는 객체들의 저장소).
메소드 영역에 로드된 클래스만 생성이 가능하고 Garbage Collector가 참조되지 않는 메모리를 확인하고 제거하는 영역이다.

4.3 Stack area (스택 영역)

지역 변수, 파라미터, 리턴 값, 연산에 사용되는 임시 값등이 생성되는 영역이다.
int a = 10; 이라는 소스를 작성했다면 정수값이 할당될 수 있는 메모리공간을 a라고 잡아두고 그 메모리 영역에 값이 10이 들어간다. 즉, 스택에 메모리에 이름이 a라고 붙여주고 값이 10인 메모리 공간을 만든다.
클래스 Person p = new Person(); 이라는 소스를 작성했다면 Person p는 스택 영역에 생성되고 new로 생성된 Person 클래스의 인스턴스는 힙 영역에 생성된다.

4.4 PC Register (PC 레지스터)

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

4.5 Native method stack

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


Heap vs Stack

  • 힙과 스택은 개발자라면 엄청나게 많이 들어본 단어일 것이다. 하지만 추상적으로는 알지만 정확한 개념은 잘 모르는 것 같아 정리해보았다.

Stack

  • 기본 타입의 변수(Int, double, byte, long etc..)에 해당하는 지역 변수, 매개 변수등이 저장
  • 메소드가 호출 될 때 메모리에 할당하고 종료되면 메모리에서 사라짐

Heap

  • 객체(인스턴스), 배열 등이 저장되는 공간
  • 객체 형태인 Integer, String, List 등의 타입이 저장된다.
  • Heap 영역에 있는 Object를 가리키는 레퍼런스 변수는 Stack에 존재
    • 예를 들어 Counter c = new Counter();라 선언하면 c는 Stack에 존재하고 Counter 객체는 힙 영역에 존재한다.

  • Counter 클래스를 가리키는 변수 sub은 Stack에 생성되고 객체는 Heap에 존재

출처 : https://jeong-pro.tistory.com/148, https://inpa.tistory.com/entry/JAVA-%E2%98%95-%EA%B7%B8%EB%A6%BC%EC%9C%BC%EB%A1%9C-%EB%B3%B4%EB%8A%94-%EC%9E%90%EB%B0%94-%EC%BD%94%EB%93%9C%EC%9D%98-%EB%A9%94%EB%AA%A8%EB%A6%AC-%EC%98%81%EC%97%AD%EC%8A%A4%ED%83%9D-%ED%9E%99#stack_%EC%98%81%EC%97%AD, chatGPT, 머리속

profile
광운대학교 정보융합학부 학생입니다.

0개의 댓글