기본타입과 참조형타입을 비교할 때 각 메모리에 저장되는 위치가 다르다고 설명하면서 메모리사용영역에 대해 언급했었다. 메모리사용영역에 대해 더 자세히 알아보자.
자바를 실행하면 JVM(Java Vitrual Machine)은 운영체제로부터 메모리를 할당받는데 이 메모리를 메소드 영역, 힙 영역, 스택 영역으로 구분하여 사용한다.
🎨 메모리 영역을 그림으로 나타내면 다음과 같다.
1) 메소드 영역
- 이 영역은 모든 스레드가 공유하는 영역이다.
- 메소드 영역에는 컴파일 된 바이트코드(.class)들이 저장되는데 코드에서 사용되는 클래스들을 클래스로더로 읽어 클래스 별로 정적필드, 상수, 메소드 코드, 생성자코드 등을 분류해서 저장한다.
2) 힙 영역
- 힙 영역에는 객체와 배열이 저장된다.
- 힙 영역에 생성된 객체와 배열은 JVM 스택 영역의 변수나 다른 객체의 필드에서 참조한다.
- 참조를 잃어버린 객체나 배열은 의미없는 객체가 되므로 쓰레기취급하고 (Garbage Collector를 실행시켜) 자동으로 제거된다.
3) 스택 영역
- 각 스레드마다 하나씩 존재하며 스레드가 시작될 때 할당된다.
- 메소드를 호출할 때 프레임을 추가(push)하고 해당 프레임은 메소드가 종료될 때 제거(pop)하는 동작을 수행한다.
- 프레임 내부에는 로컬변수스택이 있다.
- 기본 타입 변수와 참조 타입 변수가 추가되거나 제거된다.
- 초기화될 때 변수가 생성된다.
- 변수는 선언된 블록 안에서만 스택에 존재하고 블록을 벗어나면 스택에서 제거된다.
2. null은 어디에 저장될까?
참조타입 변수는 힙 영역에 객체를 참조하지 않는다는 뜻으로 null값을 가질 수 있다.
❓ 그렇다면 null은 어디에 저장될까? 힙영역일까?
🙅 null값은 초기값으로 사용할 수 있기 때문에 null로 초기화된 참조 변수는 스택영역에 생성된다.
🙋♂️ 예제를 통해 확인해보자.
String ver1 = "Hello"
String ver2 = null;
[ ver1 ]
- String객체가 heap영역에 생성되고 변수는 그 객체의 번지는 스택영역에 저장된다.
- ver1변수는 번지를 통해 객체를 참조할 수 있다.
[ ver2 ]
- ver2: null로 초기화된 참조변수는 스택영역에 생성된다.
- 참조변수가 null을 가지고 있을 경우에는 참조 객체가 없으므로 변수를 통해 객체를 사용할 수 없다.
- 만약 존재하지 않은 객체의 데이터를 사용할 경우 예외(NullPointerException)가 발생한다.
❓ 그렇다면 원래 객체를 참조했던 변수가 null로 다시 초기화하면 원래 있던 객체는 어떻게 될까?
String ver1 = "Hello";
String ver1 = null;
- 더 이상 ver1변수가 String객체를 참조하지 않아 참조를 잃은 객체는 쓰레기객체로 취급하여 쓰레기수집기(Garbage Collector)를 구동시켜 메모리에서 제거한다.
3. 요약
자바를 실행하면 JVM은 운영체제로부터 메모리를 할당받는데 이 메모리를 메소드 영역, 힙 영역, 스택 영역으로 구분하여 사용한다.
기본타입은 스택영역에 객체타입은 힙영역에 데이터가 저장된다,
null값은 객체를 참조하지 않는다는 뜻으로 null값으로 초기화된 참조 변수는 스택영역에 저장된다.