CS
JVM의 힙 & 스택 메모리
jungmin.park
2023. 12. 14. 11:17
JVM의 스택과 힙메모리 영역에 대해 아는 만큼 설명해주실 수 있을까요?
자바의 메모리 영역
자바 프로그램이 실행되면 JVM(자바 가상 머신)은 OS로부터 메모리를 할당받고, 그 메모리를 용도에 따라서 여러 영역으로 나누어 관리합니다.
JVM의 메모리 공간(Runtime Data Area)은 크게 Method(Static)영역, Stack 영역, Heap 영역으로 구분되고 데이터 타입(자료형)에 따라 각 영역에 나누어 할당 되게 된다.
- 컴파일러에 .java -> .class컴파일
- 클래스 로더에 의해서 클래스 파일을 메모리 영역에 로드 후 초기화 작업을 수행
- 메모리 영역에 Static(Method)부터 로드가 된다.
- 클래스 로드가 끝난 후 JVM은 main 메소드를 찾아 지역변수, 객체변수, 참조변수를 스택에 쌓는다.
- 로드 후 JVM이 힙 영역에 객체를 생성합니다.
- 마지막으로 실행엔진이 .class파일(바이트 코드)를 다양한 메모리를 참조하여 한줄씩 상황에 맞는 작업(함수 호출, 객체 할당)을 수행합니다.
자바 변수의 종류
변수는 크게 네 종류로 변수의 선언된 위치에 따라서 클래스변수, 인스턴스변수, 지역변수, 매개변수로 나뉜다.
변수명 | 선언위치 | 설명 |
클래스 변수 (class variable) (= static 변수) |
클래스 영역 | 클래스 영역에서 타입 앞에 static이 붙는 변수 객체를 공유하는 변수로 여러 객체에서 공통으로 사용하고 싶을 때 정의 |
인스턴스 변수 | 클래스 영역에서 static이 아닌 변수 개별적인 저장 공간으로 객체/인스턴스마다 다른 값 저장 가능 * 객체/인스턴스 생성만 하고 참조 변수가 없는 경우 가비지 컬렉터에 의해 자동 제거됨 |
|
지역 변수 (Local variable) |
메서드 영역 | 메서드 내에서 선언되고 메서드 수행이 끝나면 소멸되는 변수 초깃값을 지정한 후 사용할 수 있음. |
매개 변수 (parameter) |
메서드 호출 시 '전달하는 값'을 가지고 있는 인수 (지역 변수처럼 선언된 곳부터 수행이 끝날때까지 유효함) |
각 변수의 생성시기
- 클래스변수 : 클래스가 메모리에 올라갈때
- 인스턴스변수 : 인스턴스가 생성되었을때
- 지역변수 / 매개변수 : 위치하고 있는 메서드가 수행되었을때
Method(Static) 영역
- JVM이 동작해서 클래스가 로딩될때 생성.
- JVM이 읽어들인 클래스와 인터페이스 대한 런타임 상수 풀, 멤버 변수(필드), 클래스 변수(Static 변수), 상수(final), 생성자(constructor)와 메소드(method) 등을 저장하는 공간
- Method(Static) 영역에 있는 것은 어느곳에서나 접근 가능
- Method(Static) 영역의 데이터는 프로그램의 시작부터 종료가 될 때까지 메모리에 남아있다. 그래서 static 메모리에 있는 데이터들은 프로그램이 종료될 때까지 어디서든 사용이 가능하다. 그러나 static 데이터를 무분별하게 많이 사용할 경우 메모리 부족 현상이 일어날 수 있게 된다.
스택(Stack) 영역
- 메소드 내에서 정의하는 기본 자료형에 해당되는 지역변수의 데이터 값이 저장되는 공간
- 메소드가 호출될때 스택 영역에 스택 프레임이 생기고 그 안에 메소드를 호출
- int, double, byte, long, boolean 등에 해당되는 지역변수, 매개변수 데이터 값이 저장
- 메소드가 호출될때 메모리에 할당되고 종료되면 메모리에서 사라짐
- Stack 은 후입선출 LIFO(Last-In-First-Out)의 특성을 가지며, 스코프(Scope)의 범위를 벗어나면 스택 메모리에서 사라진다.
[ 스택 프레임(stack frame)]
하나의 메서드에 필요한 메모리 덩어리를 묶어서 스택 프레임(Stack Frame)이라고 한다.
하나의 메서드당 하나의 스택 프레임이 필요하며, 메서드를 호출하기 직전 스택프레임을 자바 Stack에 생성한 후 메서드를 호출하게 된다.
스택 프레임이 쌓이는 데이터는 메서드의 매개변수, 지역변수, 리턴값 등이 있다.
만일 메서드 호출 범위가 종료되면 스택에서 제거된다.
Heap 영역
- JVM이 관리하는 프로그램 상에서 데이터를 저장하기 위해 런타임 시 동적으로 할당하여 사용하는 영역
- 참조형(Reference Type) 데이터 타입을 갖는 객체(인스턴스), 배열 등이 저장되는 공간
- 단, Heap 영역에 있는 오브젝트들을 가리키는 레퍼런스 변수는 stack에 적재
- Heap 영역은 Stack 영역과 다르게 보관되는 메모리가 호출이 끝나더라도 삭제되지 않고 유지된다.
- 어떤 참조 변수도 Heap 영역에 있는 인스턴스를 참조하기 않게 된다면 GC(가비지 컬렉터)에 의해 메모리에서 청소된다.
- stack은 스레드 갯수마다 각각 생성되지만, heap은 몇개의 스레드가 존재하든 상관없이 단 하나의 heap 영역만 존재
힙과 스택 메모리의 차이점
스택 | 영역 | |
메모리 | 하나의 스레드가 실행될때 사용 | 애플리케이션 모든 부분에서 사용 |
메모리 접근 영역 | 다른 스레드가 접근할 수 없다. | 저장된 객체는 어디서든지 접근이 가능 |
저장 | 힙 공간에 있는 객채를 참조(주소값) primitive타입의 지역변수 |
객체가 저장 |
에러 | java.lang.StackOverFlowError | java.lang.OutOfMemoryError |
메모리 사이즈 | 힙 메모리와 비교했을 때 매우 적다. | 큰 메모리 공간을 가짐 |
속도 | 힙 메모리보다 빠름 | 속도는 다소 느리다. |
정리
스택메모리는 각 스레드마다 별도로 할당되며 일시적인 정보를 저장하는 공간입니다. 메소드가 호출될 때 스택 프레임이 만들어지고 이 프레임에는 해당 메소드의 매개변수, 지역변수, 복귀 주소 등이 저장됩니다. 메소드가 끝나면 스택은 사라지게 됩니다.
힙메모리는 객체 인스턴스와 배열이 생성될때 사용되며 각 스레드에서 모두 공유되는 메모리 영역입니다. 동적으로 생성된 데이터들이 저장되며 프로그램이 실행되는 동안 유지됩니다. 큰 메모리 공간이 필요하며 스택보다 속도는 느릴 수 있습니다.
참조