JVM의 메모리 할당방식
JVM은 기본적으로 Stack, Heap Memory 라 불리는 두 가지 저장 공간을 이용해 메모리를 할당한다.
이들에 메모리를 할당하는 방법은 바이트 코드를 한 줄 한 줄 읽는 것이다. 한 줄 한 줄 읽힌 값들은 Stack영역에 차곡차곡 쌓인다
또한 Java는 Call By Value로서 동작하는데, Java의 원시타입(Primitive Type)과 참조타입(Reference Type)에 따라 스택, 힙 메모리를 사용하는 것이 다르다.
스택 메모리 - 원시타입(Primitive Type)
힙 메모리 - 참조타입(Reference Type)
자세한 것은 아래 포스팅을 참조하기 바란다.
[항해 취업코스] 개발자 취준 기록 1일차 - Call by Reference
Call by Reference (CBR) 함수가 인수를 전달할 때 사용되는 방식에는 Call By Value(CBV), Call By Reference(CBR)가 있다. CBV는 함수가 인수로 전달받은 값을 복사하여 처리 하기 때문에 원본 값은 변경되지 않는
skroy0513.tistory.com
스택(Stack) 메모리
- 스택 메모리는 각 스레드마다 별도로 할당
- 각 메서드 호출 시 메서드에 대한 정보(매개변수, 지역변수, 복귀 주소 등)을 저장
- 메서드가 호출될 때 스택 프레임(Stack Frame)이라고 불리는 작은 블록을 생성. 이 프레임에는 해당 메서드에 대한 정보가 저장
- 메서드가 실행을 마치면 해당 스택 프레임은 스택에서 제거
- 일시적인 정보를 저장하는 공간. 함수가 호출될 때마다 작은 공간을 차지하며, 함수가 끝나면 제거.
- 작은 메모리 공간이 필요하지만 빠른 속도를 요구
메모리 할당 예제
아래와 같은 코드가 있다고 가정해 보자
public class SampleProject {
public static void main(String[] args) {
int num1 = 12;
int num2 = 15;
int numc = add(num1, num2);
}
public static int add(int a, int b) {
return a + b;
}
}
1. num1을 읽는다.
2. num2를 읽는다.
3. add() 메서드를 읽는다.
4. 결괏값을 만든다.
5. 결괏값을 numc에 할당하고 add() 메서드와 관련된 값들이 사라진다.
6. main() 메서드가 끝나고 모든 값이 사라진다.
힙(Heap) 메모리
- 힙 메모리는 객체 인스턴스와 배열이 생성될 때 사용
- 모든 스레드에서 공유되는 메모리 영역
- 객체와 배열은 동적으로 생성되기 때문에 힙 메모리에 할당
- 요약하면, 힙 메모리는 긴 시간 동안 정보를 저장하는 공간. 동적으로 생성된 데이터들이 저장되며, 프로그램이 실행되는 동안 유지. 큰 메모리 공간이 필요하지만 속도는 스택보다 느리다.
코드 한 줄을 읽었을 때 변수가 있다면 무조건 Stack에 저장되는데, 복잡한 데이터의 경우 Stack에는 변수의 주소값만 저장되고 실제 데이터는 Heap 메모리에 저장된다.
메모리 할당 예제
다음 코드를 살펴보자
public class SampleProject {
public static void main(String[] args) {
int number = 12;
Data data = new Data(15);
}
}
class Data {
public int num;
public Data(int num) {
this.num = num;
}
}
위 코드에서 Data는 복잡한 데이터이기 때문에 다음과 같이 저장된다.
Heap에 저장되는 방식
JVM의 Heap에는 복잡한 타입의 변수 클래스 타입, Interface 타입, ArrayType 등의 변수들이 저장된다. 복잡한 데이터이기 때문에 Heap의 데이터가 다시 Heap의 데이터를 참조할 수도 있다.
아래의 코드를 살펴보자
public class SampleProject {
public static void main(String[] args) {
List<Data> list = new ArrayList<>();
Data data1 = new Data(15);
Data data2 = new Data(12);
list.add(data1);
list.add(data2);
}
}
class Data {
public int num;
public Data(int num) {
this.num = num;
}
}
Stack에서 list는 Heap의 List<Data>를 가리키고 해당 list에는 Data 주소값이 2개가 있는데 각 주소값은 Data(1), Data(2)를 가리킨다.
참조
항해 개발자 취업 리부트 코스를 수강하고 작성한 콘텐츠 입니다.
IT 커리어 성장 코스 항해99, 첫 취업부터 현직자 코스까지
항해99는 실무에 집중합니다. 최단기간에 개발자/PM으로 취업하고, 현직자 코스로 폭발 성장을 이어가세요. 실전 프로젝트, 포트폴리오 멘토링, 모의 면접까지.
hanghae99.spartacodingclub.kr
'멋진 개발자 > Java & Spring' 카테고리의 다른 글
[항해 취업코스] 개발자 취준 기록 10 - Garbage Collector (0) | 2024.03.07 |
---|---|
[항해 취업코스] 개발자 취준 기록 9 - 클래스와 인스턴스의 차이 (feat. 객체) (0) | 2024.03.06 |
[항해 취업코스] 개발자 취준 기록 7 - 동시성 이슈 해결 방법 (1) | 2024.03.06 |
[항해 취업코스] 개발자 취준 기록 6 - Java의 컴파일 과정(JVM) (0) | 2024.03.05 |
[항해 취업코스] 개발자 취준 기록 5 - JVM의 구성과 특징 (0) | 2024.03.05 |