[JVM] Runtime Data Area

kims·2023년 12월 4일
0

자바

목록 보기
3/5
post-thumbnail

Runtime Data Area 구조

  • JVM이 프로그램을 수행하기 위해 운영체제로부터 할당받은 메모리 영역으로 크게 5가지 영역으로 나뉜다.

1) Method Area

  • 모든 스레드가 공유하는 메모리 공간으로, 로드된 클래스와 인터페이스의 메타데이터런타임 상수풀(Runtime Constant Pool), 정적 멤버(static)등이 저장된다.
  • Reflection API 사용해 Method 영역에 있는 클래스 정보에 접근할 수 있다.

💡 Reflection

  • 구체적인 클래스 타입을 알지 못해도 클래스의 생성자, 메서드, 변수 등에 접근할 수 있도록 도와주는 Java 기본 API

💡 Runtime Constant Pool

  • 리터럴 상수뿐만 아니라 클래스와 인터페이스명, 메서드 및 필드명 등을 저장하고, 상수에 대한 참조를 나타낸다.
    즉, 프로그램이 실행되는 동안 변하지 않는 값들이 저장된다.
  • 인덱스 1부터 시작해 상수에 대한 참조를 나타낸다.
public class Example {

    public static void main(String []args) {
        System.out.println("Hello, world");
    }
}

  • #n은 상수 풀에 대한 참조를 나타낸다.
  • 3: ldc # 13 // String Hello, world 라인에서 ldcload constant의 약자로,
    상수풀에서 상수를 로드할 때 사용하는 명령어이다.

2) Heap Area

  • 모든 스레드가 공유하는 메모리 공간으로 객체를 생성할 때마다 메모리 공간이 할당된다.
    따라서, dead code(실행되지 않는 코드)라면 힙 영역에 할당되지 않는다.

  • 참조 타입(Reference type)이 Heap 영역에 저장되는 이유는 객체가 동적으로 생성되고 내부 참조 크기가 동적으로 변하기 때문이다.

    구분32-bit JVM64-bit JVM
    내부 참조 크기14 bytes8 bytes
    최대 메모리 공간22322^{32}2642^{64}
1: 참조 타입 크기
2: 전체 힙 메모리 크기
  • GC(Garbage Collection)의 대상이 된다.
  • Heap 메모리 공간이 부족하면 Java.lang.OutOfMemoryError : java heap space 에러가 발생한다.
    공간 부족의 원인은 Heap 메모리 공간의 크기가 작거나 애플리케이션 로직 문제로 발생하는 경우가 있다.

OOME(java. lang.OutOfMemoryError) 해결 방법

  • Heap 메모리 공간은 -Xms(초기 힙 크기), -Xmx(최대 힙 크기) 옵션을 사용해 제어 가능하다.
  • OOME 발생 시점에 생성된 Heap Dump를 분석해 메모리 누수를 유발하는 로직을 수정한다.

💡 idea64.exe.vmoptions

  • IntelliJ IDEA 실행 시 JVM 옵션을 주는 파일
    IntelliJ IDEA 실행 시 JVM 옵션을 주는 파일

3) Stack Area

  • 메서드 호출 정보를 저장하는 공간으로 각 스레드(Thread)별로 생성된다.
    단, 다른 스레드 간 접근은 불가하다.
  • 스택(Stack)의 수명은 스레드의 수명에 따라 달라지며, 스레드가 살아있으면 스택도 살아있게 되고 그 반대의 경우도 마찬가지이다.
  • 메서드가 호출될 때 마다 새로운 프레임(Frame)이 호출 스택(Call Stack)3에 추가(Push)되고, 메서드가 종료되면 해당 프레임이 스택에서 제거(Pop) 된다.
3: 메서드 호출을 기록하는 스택 자료구조
  • 지정한 Stack 메모리 크기보다 더 많은 메모리를 사용하게 되면 Java.lang.StackOverFlowError 에러가 발생한다.
    원인은 재귀함수를 사용하거나 상호 참조(본인참조 포함) 문제로 발생하는 경우가 있다.

Stack Overflow 해결 방법

  • 재귀함수 호출 시 이전의 호출한 스택 메모리를 종료시킬 수 있도록 하면 된다. 즉, 다음 함수 호출시 현재 함수의 결과 값을 전달하면 된다.
  • 참조 시 클래스 내에서 인스턴스를 직접 생성하지 않고 주입을 통해 인스턴스를 생성하면 된다.

💡 Thread

  • 프로세스(process: 실행 중인 프로그램) 내에서 실제로 작업을 수행하는 주체이자 실행 단위

💡 Frame

  • 메서드 호출에 대한 정보를 저장 (매개변수 및 지역변수, 리턴 값 등)

4) PC Registers

  • 스레드의 현재 수행 중인 명령어의 주소를 저장하는 공간으로, 각 스레드(Thread)별로 생성된다.

5) Native Method Stacks

  • 자바이외의 언어로 작성된 네이티브 코드를 위한 스택으로, JNI(Java Native Interface)를 통해 호출하는 C, C++ 등의 코드를 수행하기 위한 스택

💡 JNI(Java Native Interface)

  • JVM 위에서 실행되고 있는 자바코드다른 언어들(C, C++ 등)로 작성된 라이브러리들을 호출하거나 반대로 호출되는 것을 가능하게 하는 프로그래밍 프레임워크

💡참고

profile
기술로 세상을 이롭게

0개의 댓글