Machine/JVM

[메모리] JVM의 메모리 사용 방식 : JVM의 Static Area와 Heap Area를 중심으로 Kotlin/JVM의 메모리 사용방식을 이해하기

반응형

목표

  • 각 Memory Area가 어떤 역할을 하는지 이해한다.

JVM의 메모리 구조

그림1. JVM의 메모리 구조

 JVM은 Runtime에 Data를 올려놓는 공간인 Runtime Data Area를 가지고 있다. 이 공간은 총 5가지로 나뉘는데, 뒤의 PC Register과 Native Method Stack 영역은 Low Level의 Operation을 하기 위한 메모리 공간 이므로 이 장에서는 앞의 세가지 'Method Area(Static Area)', 'Heap Area', 'Stack Area'만 다룬다.

 

  • Method Area(Static Area) - 정적 영역
  • Heap Area - 힙 영역
  • Stack Area - 스택 영역

Method Area(Static Area)

 

그림2. Method Area에 데이터가 적재되는 과정

개요

Method Area는 우리가 보통 정적(Static) 영역이라고 부르는 메모리이다. 프로그램 실행 중 클래스나 인터페이스를 사용하게 되면, JVM은 Class Loader을 이용해 클래스와 인터페이스의 메타 데이터를 Method Area에 저장한다. 즉, 클래스가 로드 되는 시점은 해당 클래스가 사용되기 위해 호출되는 시점이다. 여기서 메타 데이터는 Type Information, Runtime Constant Pool, Field Information, Method Information, Class Variable을 가리킨다.

 

Method Area에 저장되는 목록

1. Type Information : 클래스와 인터페이스의 정보이다.

  • Type명 : Package name + Class name
  • Type의 종류 : Type이 Class인지 Interface인지에 대한 정보
  • Type의 제어자 : 접근 제어자(public, private, default 등), 그 외 제어자 (abstract, final 등)
  • 연관된 Interface 정보 : 사용된 Interface의 정보

 

2. Runtime Constant Pool : Type의 상수 정보를 저장하는 Pool이다. 각 상수로는 인덱스를 통해 접근 가능하다.

  • Type, Field, Method로 접근하기 위한 Reference 정보 - 객체 접근을 위해 필요하다.

 

3. Field Information : 인스턴스 변수의 정보를 저장한다.

  • Type명 : 인스턴스 변수의 타입
  • 제어자 : 접근 제어자(public, private 등), 그 외 제어자(static, final, volatile 등)

4. Method Information : 메서드의 모든 정보를 저장한다.

  • Method 명
  • Method 반환 타입
  • Method parameter수와 각 parameter의 타입 정보
  • 외 필요한 메서드에 대한 정보들

5. Class Variable : static 키워드로 선언된 변수가 저장된다.


Stack Area

 

그림3. 다중 Thread 환경에서 공유되는 메모리와 공통으로 사용되는 메모리 영역 

 

개요

 Stack Area는 메서드가 호출될 시 할당되는 영역이다. 메서드 호출 시 메서드 내부의 지역 변수 또한 Stack Area에 할당된다. 여기서 할당된다는 뜻은 Heap 공간에 객체 데이터를 올리고 그 객체 데이터에 대한 참조값이 할당된다는 뜻이다. 예외적으로 원시 타입(Primitive type) 변수는 Stack 영역에 값 자체가 할당된다.

 Stack에서 꼭 알고 가야할 점이 있다. 우리는 프로그래밍을 하면서 코어를 최대한 활용하기 위해 Thread를 사용하여 프로그래밍을 하는데, 각 스레드는 하나의 Stack 영역을 할당 받는다. 즉, 스레드는 각자의 메모리 공간을 가지고 메서드를 수행하는 것이다. 

 

Stack Area에 저장되는 목록

1. Heap 영역에 생성되는 객체의 참조값

2. 원시 타입의 경우 데이터 자체가 저장됨

 


Heap Area

개요

 Heap Area는 프로그램이 실행되면서 동적으로 생성된 객체(인스턴스)가 저장되는 공간이다. Heap Area에 생성된 객체들은 다른 객체의 필드 또는 스택에 존재하는 다른 메서드에 의해 참조될 수 있다. 메서드가 실행되면서 Stack영역에는 참조값만을 저장해놓고 Heap Area에 객체 데이터를 저장해 놓는다. 

 우리가 많이 아는 자료구조에 관한 내용이 Heap Area에서 많이 쓰인다. 예를 들어 아래와 같이 배열과 리스트가 선언되었다고 해보자. 이런 경우 Stack 영역에는 참조값만 저장되며 Heap 영역에 실제 데이터가 저장된다.

var arrayExample: Array<String> = arrayOf("a", "b", "c")
var listExample: List<String> = listOf("a", "b", "c")

그림4. Array와 List가 저장되는 방법

* listOf는 Arrays.asList로 array를 전달하여 ArrayList를 생성하므로 위와 같은 결과가 나온다.

Heap Area에 저장되는 목록

1. 객체의 데이터

반응형

 

이 글의 저작권은 Kotlin World 에 있습니다. 글, 이미지 무단 재배포 및 변경을 금지합니다.