DEV/Java

[java] JVM 메모리 구조와 변수별 메모리 할당

Bi3a 2023. 10. 23. 10:51

반응형

[java] JVM 메모리 구조와 변수별 메모리 할당
java 기초 깨부시기

 


 

부트캠프 강의 중 JVM 메모리구조와 변수별 메모리 할당에 대해 학습이 필요할 것 같아서 해보는 정리!!

 

JVM의 메모리 구조

JVM의 메모리 구조는 크게 5개의 구조로 나뉩니다.

 

JVM 메모리 구조
JVM 구조 : 크게 힙(heap), 스택(stack), 메소드 영역, 네이티브 메소드 스택 (+ PC 레지스터) 으로 나뉩니다.

 

  • 스택(Stack)
    • 메서드 호출과 관련된 정보를 저장하는 데 사용합니다.
    • 데이터를 빠르게 할당하고 제거할 수 있으며, 그에 따른 메모리 할당 및 해제가 자동으로 이뤄집니다.
    • 각 호출마다 프레임 단위로 메모리가 할당되는데, 이를 스택 프레임이라고 합니다. 
      • 스택 프레임은 이름에 걸맞게 FILO, LIFO 구조를 가집니다. (메서드 실행에 따른 push, 종료 시 pop)
      • 스택 프레임에 지역변수, 매개변수, 복귀 주소, 메소드 호출 정보 등이 저장됩니다.
      • 메서드에 활용되는 원시 변수와 참조 변수(객체를 참조하는 변수 등) 저장됩니다.
      • 저장된 데이터 수명은 메서드 실행 범위에 한정하며, 메서드 종료 시 스택 프레임과 함께 제거됩니다.

 

  • 힙(Heap)
    • 동적으로 저장된 객체(인스턴스)를 저장하는 데 사용합니다.
    • 객체는 프로그램 실행 도중 new 연산자를 통해 동적으로 생성되어 힙에 저장됩니다.
    • 힙에 저장된 객체들은 JVM의 가비지 컬렉터(Garbage Collector) 를 통해 자동으로 관리됩니다.
      • 더 이상 참조되지 않는 객체는 메모리에서 해제됩니다.

 

  • 메서드 영역(Method Area) / 코드 영역(Code Area)
    • 클래스 정보, 메서드 코드, 상수 풀, 정적 변수, 메서드 및 생성자 정보 등을 저장하는 공간입니다.
    • 프로그램 실행 동안 변하지 않는 데이터와 코드를 저장하는 영역입니다.
    • 프로그램이 시작될 때 초기화되고, 프로그램 종료 시 까지 유지됩니다.
    • Java 8 이전에는 PermGen, 이후에는 Metaspace라는 영역으로 불립니다.

 

  • 네이티브 메소드 스택(Native Method Stacks)
    • 네이티브 메소드(네이티브 코드, 자바 외부 코드로 작성된 메서드)를 사용할 때 해당 호출 정보를 저장합니다.
    • 자바 외부에서 구현되며, 스택 구조로 구현됩니다.

 

  • PC 레지스터(Program Counter Register)
    • 현재 실행중인 스레드의 명령어 주소를 가리키고, 저장합니다.
    • 각 스레드마다 다른 PC 레지스터를 가집니다.

 

 

java 변수 유형에 따른 메모리 크기와 저장

java 변수 유형별 메모리 크기

구  분 변수 크  기 비  고
원시형 byte 1 바이트  
원시형 short 2 바이트  
원시형 int 4 바이트  
원시형 long 8 바이트  
원시형 float 4 바이트  
원시형 double 8 바이트  
원시형 char 2 바이트  
원시형 boolean  1 바이트*  JVM, 컴파일러 별 상이
참조형 참조 변수 8 바이트* JVM, 컴파일러 별 상이

 

 

참조형 변수의 크기가 같을 수 있는 이유?
참조형 변수의 크기가 같을 수 있는 이유는 참조형 변수의 주소는 가리키는 내용(객체)의 첫 번째 위치만을 기억하고 있기 때문입니다.

기본적으로 모든 참조형 변수의 크기는 같습니다. 참조형 변수는 본질적으로 객체를 가리키는 주소기 때문입니다.
그렇기 때문에 객체의 크기가 다양하지만 , 그 객체를  참조하는 변수들의 크기는 모두 동일할 수 있습니다.

 

java 변수 유형별 메모리 할당

  • 클래스 정보(생성자, 메소드 호출 방법 등), 정적 변수(static) : 메서드 영역
  • 지역변수(원시형, 참조형) : 스택 영역
  • 생성된 인스턴스 : 힙 영역

 

java 변수 유형별 메모리 할당(코드 예시)

public class MemoryExample {
    public static void main(String[] args) {
        int num = 42; // "num" 변수는 스택에 저장됨
        String name = "John"; // "name" 변수는 스택에 저장되지만, 문자열 데이터는 힙에 저장됨

	// "Person"이라는 클래스 정보 자체는 메소드 영역에 저장
        Person person = new Person("Alice"); // "person" 변수는 스택에 저장되며, Person 객체는 힙에 저장됨
    }
}
  • 변수 유형별 저장되는 장소
    • 메소드 영역 : `main 클래스`, `Person 클래스(+생성자)`, `MemoryExample 클래스`
    • 스택 영역 : `int num`, `String name`, `Person person`
    • 힙 영역 : `String name`의 데이터인 `"John"`, `person의 객체` 

 

참고하면 좋을 사이트

https://cscircles.cemc.uwaterloo.ca/java_visualize/

자바 비주얼라이저 : 라인 단위 코드 실행마다 메모리가 어떤 식으로 할당되는 지를 시각화해 보여주는 사이트

 

반응형