본문 바로가기

p-languages/java

java/ 배열 공부 전 이해해야 할 stack, heap 영역과 참조 타입 변수 간단 정리

JVM; Java Virtual Machine

JVM은 운영체제에서 할당받은 메모리 영역을 세부 영역으로 구분해서 사용한다.

 

1. 메소드method 영역

JVM이 시작할 때 생성되어 모든 스레드가 공유한다. class들을 클래스 로더로 읽어 클래스별로 static field(필드), constant(상수), method(메소드) code, constructor(생성자) code 등을 분류해서 저장한다.

 

2. 힙heap 영역

객체와 배열이 생성되는 영역.

힙 영역에서 생성된 객체와 배열은 JVM 스택 영역의 변수나 다른 객체의 필드에서 참조한다.

if 참조하는 변수나 필드가 없다? >> garbage collector를 실행시켜 자동으로 제거한다. (의미 없는 객체)

  • new 연산자: 객체 생성 연산자로 heap 영역에 새로운 객체를 만든다.

3. JVM 스택stack

메소드를 호출할 때마다 프레임을 추가(push)하고 메소드가 종료되면 해당 프레임을 제거(pop)하는 동작을 수행한다. 

  • 프레임 내부 - 로컬 변수 스택: 기본 타입 변수와 참조 타입 변수가 추가되거나 제거된다.
  • 스택 영역에 변수가 생성되는 시점은 최초에 변수에 값이 저장될 때(initialized)
  • 변수는 선언된 블록 안에서만 스택에 존재하고 블록을 벗어나면 스택에서 제거된다 (eg. if/for문 안에서 선언 된 변수는 블록 밖에서 사용할 수 없다)

기본적으로 코드를 작성하는 부분은 스택 영역, 스택 영역에서 작성한 참조 타입 변수가 참조하는 번지(객체)는 힙 영역에 존재한다고 이해한다.


변수

기본 타입 변수

  • 실제 값을 저장한다
  • eg. byte, short, char, int, long, float, double, boolean

 

참조 타입 변수

  • 메모리의 번지(주소)를 저장한다. > 번지를 통해 객체를 참조한다.
  • eg. 배열, 열거, 클래스, 인터페이스
  • heap 영역의 객체 주소 값을 갖고 있다. 번지를 통해 객체를 참조한다.

기본 타입 변수는 스택 영역에서 직접 값을 갖고 있지만

참조 타입 변수는 스택 영역에서 힙 영역의 객체 주소를 가진다.

int[] arr = new int[] {1, 2, 3};

스택 영역에서 생성된 배열 변수 arr에는 배열의 heap 영역의 주소를 저장한다. 실제 배열 {1, 2, 3}은 heap 영역에서 생성된다.


Null

Null참조 타입 변수가 heap 영역의 객체를 참조하지 않는다.

 

참조 타입 변수가 null 값을 가진다는 것은 참조하는 객체가 없다는 뜻이다. 이 경우 변수를 통해 객체를 사용하는 것은 불가능하다. 따라서 null 값을 갖는 변수를 통해 객체를 사용하려고 하면 NullPointerException 이 발생한다.

int[] arr = null; //배열 변수 arr를 null로 초기화한다
arr[0] = 1; //NullPointerException

배열 변수 arr을 null로 초기화했다는 것은 변수 arr이 참조할 객체가 없다는 의미이다. 따라서 arr[0]에 값을 저장하는 것은 불가능하고 NullPointerException이 발생하게 된다.


요약

기본 타입 변수와 참조 타입 변수 모두 stack 영역에서 생성된다.

기본 타입 변수에 저장되는 값은 실제 값으로 stack  영역에 함께 저장된다.

참조 타입 변수는 stack 영역에서 객체의 번지를 저장하고, 객체는 heap 영역에서 생성되어 객체에 저장된 값은 번지를 통해 참조된다.

 

 

reference. 신용권, 혼자 공부하는 자바, 한빛미디어, 2019