Java/Basic

[Java-Basic] JVM 메모리구조 및 개념

Jeong Jeon
반응형

JVM(Java Virtual Machine) 이란?

  • 자바 가상 머신으로 자바 바이트 코드를 실행할 수 있는 주체
  • CPU나 운영체제(플랫폼)의 종류와 무관하게 실행이 가능

운영체제 위에서 동작하는 프로세스로 자바 코드를 컴파일해서 얻은 바이트 코드를 해당 운영체제가 이해할 수 있는 기계어로 바꿔 실행시켜주는 역할을 한다.

 

JVM은 크게 ClassLoader / Execution Engine / Garbage Collector / Runtime Data Area 로 나뉜다.

각각의 아이들이 무엇을 의미하는지 알아보자.!

 

 

JVM의 구성

  • Class Loader
    • Java 소스파일 (.java)를 .class 파일(바이트코드)로 컴파일 한다.
    • 생성된 클래스파일들을 엮어서 JVM이 운영체제로부터 할당받은 메모리영역인 Runtime Data Area로 적재하는 역할.

여기서 바이트코드를 짚고 넘어가자!

 

바이트코드(byte code)는 특정 하드웨어가 아닌 가상 머신에서의 실행 프로그램을 위한 이진 표현법으로, 
하드웨어가 아닌 소프트웨어에 의해 처리되기 때문에, 보통 기계어보다 더 추상적이다.
  • Execution Engine
    • Class Loader에 의해 메모리에 적재된 클래스(바이트 코드)들을 기계어로 변경해 명령어 단위로 실행
    • 명령어를 하나 하나 실행하는 인터프리터(Interpreter)방식이 있고 JIT(Just-In-Time) 컴파일러를 이용하는 방식이 있다.
    • JIT 컴파일러는 적절한 시간에 전체 바이트 코드를 네이티브 코드로 변경해서 Execution Engine이 네이티브로 컴파일된 코드를 실행하는 것으로 성능을 높이는 방식 == 자연어(바이트코드) => 기계어 전환
  • Garbage Collector
    • Garbage Collector(GC)는 Heap 메모리 영역에 생성(적재)된 객체들 중에 참조되지 않는 객체들을 탐색 후 제거하는 역할
    • GC가 수행되는 동안 GC를 수행하는 쓰레드가 아닌 다른 모든 쓰레드가 일시정지된다 유의
      • Full GC가 일어나서 수 초간 모든 쓰레드가 정지한다면 장애로 이어지는 치명적인 문제가 생길 수 있는 것이다. 
    • GC가 역할을 하는 시간은 정확히 언제인지를 알 수 없다. (참조가 없어지자마자 해제되는 것을 보장하지 않음) ==> 알아서 처리하기 때문..!
  • Runtime Data Area
    • JVM의 메모리 영역으로 자바 애플리케이션에 사용되는 데이터들을 적재하는 영역
      크게 Method Area, Heap Area, Stack Area, PC Register, Native Method Stack로 나눌 수 있다.

우리는 여기서 Runtime Data Area , 메모리 영역을 중점적으로 봐야한다.

JVM의 메모리 구조는 위 사진과 같이 이루어져있는데, 우리는 우선 Method Area(static), Heap Area, Stack Area 정도는 확실히 알고있어야 한다.

 

1. Method area (메소드 영역)

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

 

2. Heap area (힙 영역)

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

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

우리는 Heap 영역을 중요하게 여겨봐야한다.

이아이만 조금더 자세히 살펴보도록 하자!!!

힙 영역은 효율적인 GC를 위해 Eden, Survivor1, Survivor2, Old 영역, Permanent영역( 생성된 객체들의 주소값이 저장되는 영역 )으로 나누어집니다. 

어떤식으로 Heap 메모리의 GC가 이루어지는지 보도록하자..!

처음 new를 통해 생성된 객체는 Eden영역에 존재하게 된다. => 이때 Eden영역이 새롭게 생긴 객체들로 꽉차게 된다면 First GC가 발생한다. => Eden영역의 참조되지 않은 객체를 제거하고 참조가 유지되는 객체는 Survivor1 (S1이라칭한다)로 이동시킨다. =>  다시 new를 통한 객체가 생성중 또 Eden 영역이 가득 차게 되면 참조를 유지하고 있는 객체들을 S1 영역이 아닌 S2 영역으로 이동시킵니다. 동시에 S1 영역에 있는 객체 중 참조가 유지되고 있는 객체 또한 S2로 이동시키고 age를 +1 합니다. 이를 Minor GC라고 한다. => Eden -> S1 -> S2->S1…이 반복적으로 이루어지다보면 S2에 age가 많은 객체들이 생기는데, 이객체들은 Old영역으로 이동하게 된다. 이때 Old영역에 있는 객체들 중 참조되지 않은 객체들을 싹 조사하는데 이를 Major GC라고 한다.  Major GC는 한번에 참조되지 않는 객체들을 모아 제거하게 되는데, 이를 FUll GC라고 한다.

 

3. Stack area (스택 영역)

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

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

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

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

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

 

4. PC Register (PC 레지스터)

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

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

 

5. Native method stack

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

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

 

 

Java 개발자로써 알아야하는 부분인데 간단하게 GC는 Heap메모리에 사용안하는 아이들을 제거해준다 라고만 알고, JVM은 아 java 가상 머신, 컴파일해주고, 운영체제에 상관없이 Java를 돌려주는 아이구나 했다.

조금씩 조금씩 제대로된 지식을 담아보자!

 

모두들 오늘도 화이팅!

반응형