LostCatBox

Java Basic JVM

Word count: 1.2kReading time: 7 min
2022/12/25 Share

JVM에 대한 전반적인 설명

Created Time: November 14, 2022 5:06 PM
Last Edited Time: December 21, 2022 1:31 PM
References: https://velog.io/@litien/JVM-%EA%B5%AC%EC%A1%B0
https://www.youtube.com/watch?v=zta7kVTVkuk
https://8iggy.tistory.com/229
Tags: Java, Spring

Java란?

다시 읽어보기

https://8iggy.tistory.com/229

https://mangkyu.tistory.com/106

JVM 이란?

JVM은 자바 가상머신으로 자바 바이트코드를 실행 할 수 있는 주체로 JVM 덕분에 CPU나 운영체제(플랫폼)과 독립적으로 동작 가능하다

JVM은 크게 Class Loader, Runtime Data Area, Excute engine 3가지로 나뉜다

1

Method Area와 Heap은 모든 쓰레드가 공유
JVMStack, PC Registers,NativeMethodStacks는 쓰레드 생성시 매번 생성됨

자바 애플리케이션 실행 과정

  1. 어플리케이션이 실행되면 JVM이 OS로부터 메모리를 할당 받음
    • JVM은 할당 받은 메모리를 용도에 따라 영역을 구분하여 관리
  2. 자바 컴파일러(iavac.exe)가 자바 소스코드(iava)를 읽어 바이트 코드(.class)로 변환
  3. Class Loader를 통해 바이트 코드를 JVM(Method Area)으로 로딩
  4. 로딩된 바이트 코드는 Execution Engine을 통해 해석됨
    (바이트코드→기계어)
  5. 해석된 바이트 코드는 Runtime Data Areas에 배치되어 실행됨
    • 실행되는 과정에서 GC 같은 작업이 수행됨
    • Runtime Data Areas 이 실질적으로 메모리를 할당받아, 관리하는 곳

Class Loader

2

  • JVM으로 바이트 코드(class)를 로드하고, 링크를 통해 배치하는 작업을 수행하는 모듈
  • 로드된 바이트 코드들을 엮어서 JVM의 메모리 영역인 Runtime Data Areas에 배치함
  • 클래스를 메모리에 올리는 로딩 기능은 한번에 메모리에 올리지 않고, 어플리케이션에서 필요한 경우(호출시) 동적으로 메모리에 적재하게 됨
  • 클래스 파일의 로딩은 3단계로 구성됨
    Loading → Linking → Initialization

Runtime Data Area(자바 메모리 공간)

3

Untitled

어플리케이션이 동작하기 위해 OS에서 할당받은 메모리 공간을 의미

크게 5가지로 구성되어 있음

  • Method Area
  • Heap Area
  • Stack Area
  • PC Register
  • Native Method Stack

Method Area

• 클래스 로더에 의해 로드된 클래스, 메소드 정보와 클래스 변수 정보 저장(meta-data) 모든 스레드가 공유하는 영역(cv, iv는 heap에 생성됨)(lv는 stack)

Method Area에는 Runtime Constant Pool이라는 별도의 영역이 존재

  • 상수 자료형을 저장하여 참조하는 역할

저장되는 정보의 종류

  • Field Info : 멤버 변수의 이름, 데이터 타입, 접근 제어자의 정보
  • Method Info : 메소드 이름, Return 타입, 매개변수, 접근 제어자의 정보
  • Type Info : Class인지 Interface인지 여부 저장, Type의 속성, 이름, Super Class의 이름

Heap과 마찬가지로 GC 관리 대상임(잘일어나지는않는다)

Method Area와 Heap Area는 여러 스레드들 간에 공유되는 메모리

Heap Area

5

객체를 저장하기 위한 메모리 영역, 모든 스레드가 공유하는 영역(static 변수도 힙 저장)

new 연산자로 생성된 모든 Object와 Instance 변수, 그리고 배열을 저장

Heap 영역은 물리적으로 두 영역으로 구분할 수 있음 (Young Generation, Old Generation)

  • Young Generation : 생명 주기가 짧은 객체를 GC 대상으로 하는 영역
    Eden에 할당 후 Survivor 0과 1을 거쳐 오래 사용되는 객체를 Old Generation으로 이동시킴
  • Old Generation : 생명 주기가 긴 객체를 GC 대상으로 하는 영역

Garbage Collection 생명주기에 의해 지속적으로 메모리가 정리됨

  • Minor GC
  • Major GC

Method Area와 Heap Area는 여러 스레드들 간에 공유되는 메모리

static 변수는 어디에 저장?

  • static 변수는 permanent에 값을 저장한다.
  • permanent 영역은 프로그램 시작시 할당되고, 종료시까지 저장되어있다.
    • primitive 변수 값 저장
    • Reference 변수의 참조값은 Permanet에 저장하고, new Object() 객체는 Young Generation에 저장됨.→ 항상 참조가 되고있으므로 GC로 사라지지않음.
  • 현재 metaspace는 여전히 static object에 대한 reference를 보관하며 애매하게 heap에 걸쳐지지 않고 non-heap(native memory)로 이관되며 static 변수(primitive type, interned string)는 heap 영역으로 옮겨짐에 따라 GC의 대상이 될 수 있게끔 조치한 것이다.

Stack Area

스크린샷 2022-11-14 오후 6.31.02.png

각 스레드를 위한 분리된 Runtime Stack 영역
메소드를 호출할 때 마다 Stack Frame으로 불리는 Entry Stack Area에 생성됨(Stack Frame은 각각 LVA,OS,FD를 가짐)
스레드의 역할이 종료되면 바로 소멸되는 특성의 데이터를 저장
각종 형태의 변수나 임시 데이터, 스레드 또는 메소드의 정보를 저장(지역변수, 메서드 매개변수 등)

7

참조

예시

primitive type은 값을 가짐

reference type은 참조값을 가짐! → 실제 객체는 heap영역에 저장되고, 변수는 힙의 참조값을 값으로 가짐

8

PC Register

9

PC는 Program Counter의 줄임말

각 Thread가 시작될 때 생성되며, 현재 실행중인 상태 정보를 저장하는 영역

Thread가 로직을 처리하면서 지속적으로 갱신됨

Thread가 생성될 때마다 하나씩 존재함

어떤 명령을 실행해야 할지에 대한 기록 (현재 수행 중인 부분의 주소를 가짐)

Native Method Stack

바이트 코드가 아닌 실제 실행할 수 있는 기계어로 작성된 프로그램을 실행 시키는 영역

Java가 아닌 다른 언어로 작성된 코드를 위한 영역

Java Code를 수행하다 JNI 호출 시 Java Stack에서 Native Stack으로 동적 연결(Dynamic Linking)을 통해 확장됨

JNI(java native interface)를 통해 바이트 코드로 전환하여 저장

각 스레드 별로 생성됨

JNI(Java Native Interface)

자바가 다른 언어로 만들어진 어플리케이션과 상호 작용할 수 있는 인터페이스를 제공
JVM이 Native Method를 적재하고 수행할 수 있도록 함
실질적으로 제대로 동작하는 언어는 C/ C++

10

Execution Engine

11

Runtime Data Area에 할당된 바이트 코드를 실행시키는 주체

코드를 실행하는 방식은 크게 2가지 방식이 존재

Interpreter

  • 바이트 코드를 해석하여 실행하는 역할을 수행
  • 다만 같은 메소드라도 여러번 호출될 때 매번 새로 수행해야 함

JIT(Just In Time) Compiler

  • Interpreter의 단점을 해소
  • 반복되는 코드를 발견하여 전체 바이트 코드를 컴파일하고 그것을 Native Code로 변경하여 사용

Garbage Collector

  • 더이상 참조되지 않는 메모리 객체를 모아 제거하는 역할을 수행
  • 일반적으로 자동으로 실행되지만, 수동으로 실행하기 위해
    ‘System. gct’를 사용할 수 있음 (다만, 실행이 보장되지는 않음)
  • 앞으로 사용되지 않는 객체의 메모리를 Garbage라고 부름
  • 이런 Garbage를 정해진 스케줄에 의해 정리해주는 것을 GC(Garbage Collection)라 부름

Stop The World

  • GC를 수행하기 위해 JVM이 멈추는 현상을 의미
  • GC가 작동하는 동안 GC관련 Thread를 제외한 모든 Thread는 멈춤 일반적으로 ‘튜닝’이라는 것은 이 시간을 최소화하는 것을 의미함(퍼포먼스튜닝)

GC의 종류

  • Serial GC
  • Parallel GC
  • CMS GC
  • G1 GC
  • Z GC

전체 그림

12

13

14

ClassLoader로 wootaco.class를 MethodArea에 넣음

wootaco.class에서 bytecode 실행시작→main메서드 실행(이때 항상 Constant Pool을 바라보고있음)

그후 new Crew()에 해당하는 코드 실행중 com.example.Crew를 실행시 Method Area에 없으므로 해당 class 를 Class Loader에게 요청하고 Method Area에 로드

15클래스 변수와 인스턴스 변수도 이제 설명가능하다

Untitled

클래스 변수(Static 멤버)(cv)

  • 클래스 내에 Static 키워드로 선언된 변수
  • 처음 JVM이 실행되어 클래스가 메모리에 올라갈 때 ~ 프로그램이 종료될 때까지 유지
  • 클래스가 여러 번 생성되어도 Static 변수는 처음 딱 한 번만 생성됨
  • 동일한 클래스의 모든 객체들에 의해서 공유됨(Heap에 PermanentHeap또는 Heap에포함)

인스턴스 변수(Non-static 멤버)(iv)

  • 클래스 내에 선언된 변수
  • 객체 생성 시마다 매번 새로운 변수가 생성됨
    (힙에 존재)
  • 클래스 변수와 달리 공유되지 않음

아래 예제에서 StaticTest 인스턴스를 두 개 생성한 후 staticTest1의 클래스 변수와 인스턴스 변수를 수정해보았다.

클래스 변수 classVar은 처음 한 번만 생성되고 동일한 객체를 staticTest1staticTest2 에서 서로 공유하기 때문에 양쪽이 동시에 바뀌었지만 instanceVar은 객체 생성 시 마다 매번 새로 메모리에 할당되기 때문에 staticTest1.instanceVar만 변경된 것을 확인할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public static class StaticTest {
static intclassVar= 10; //클래스 변수 == static 변수
int instanceVar = 28; //인스턴스 변수 == non static 변수
}
public static void main(String[] args) {
StaticTest staticTest1 = new StaticTest();
StaticTest staticTest2 = new StaticTest();
System.out.println("1. " + staticTest1.classVar+ "," + staticTest1.instanceVar);
System.out.println("2. " + staticTest2.classVar+ "," + staticTest2.instanceVar);

staticTest1.classVar= 12;
staticTest1.instanceVar = 400;
System.out.println();
System.out.println("1. " + staticTest1.classVar+ "," + staticTest1.instanceVar);
System.out.println("2. " + staticTest2.classVar+ "," + staticTest2.instanceVar);
}

main() 함수

public static main (String[] args(){

}

CATALOG
  1. 1. JVM에 대한 전반적인 설명
  2. 2. Java란?
  3. 3. 다시 읽어보기
  4. 4. JVM 이란?
    1. 4.1. 자바 애플리케이션 실행 과정
    2. 4.2. Class Loader
    3. 4.3. Runtime Data Area(자바 메모리 공간)
      1. 4.3.1. Method Area
      2. 4.3.2. Heap Area
      3. 4.3.3. static 변수는 어디에 저장?
      4. 4.3.4. Stack Area
      5. 4.3.5. PC Register
      6. 4.3.6. Native Method Stack
    4. 4.4. Execution Engine
      1. 4.4.1. Interpreter
      2. 4.4.2. JIT(Just In Time) Compiler
      3. 4.4.3. Garbage Collector
  5. 5. 전체 그림
    1. 5.0.1. 클래스 변수(Static 멤버)(cv)
    2. 5.0.2. 인스턴스 변수(Non-static 멤버)(iv)
  • 6. main() 함수