Java

[Java] 참조 타입

최MAX 2022. 3. 22. 18:44

JVM (Java Virtual Machine)이 사용하는 메모리 영역

 

java.exe로 JVM이 시작되면 JVM은 운영체제에서 할당받은 메모리 영역 (Runtime Data Area)를 아래와 같은 세부 영역으로 구분해서 사용.


 메소드 (Method) 영역

코드에서 사용되는 클래스(~.class)들을 클래스 로더로 읽어 클래스별로 [런타임 상수풀(runtime constant pool)], [필드 (filed) 데이터], [메소드 (method) 데이터], [메소드 코드], [생성자 (Constructor) 코드] 등을 분류해서 저장.

JVM이 시작할 때 생성되고 모든 스레드가 공유하는 영역

 

 힙 (Heap) 영역

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

참조하는 변수나 필드가 없다면 JVM은 이것을 쓰레기로 취급하고 쓰레기 수집기 (Garbage Collector)를 실행시켜 이를 자동으로 힙 영역에서 제거함.

 

 JVM 스택(Stack) 영역

각 스레드마다 하나씩 존재하며 스레드가 시작될 때 할당된다.

JVM 스택은 메소드를 호출할 때마다 프레임(Frame)을 추가(push)하고 메소드가 종료되면 해당 프레임을 제거(pop)한다.

변수는 선언된 블록 안에서만 스택에 존재하고 블록을 벗어나면 스택에서 제거된다.

기본 타입 변수 (int, double, long 등)는 스택에 직접 값을 가지고 있지만. 참조 타입 변수는 값이 아닌 힙 영역이나 메소드 영역의 객체 주소를 가진다. 

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

다음과 같은 배열 변수인 arr는 스택 영역에 생성되지만 실제 {1, 2, 3, 4}을 가진 배열은 힙 영역에 생성된다. 따라서 arr에는 배열의 힙 영역의 주소가 저장된다.

 


 

NullPointerException

null을 가지고 있는 참조 타입 변수를 사용하면 발생


int[] arr = null;
arr[0] = 10;  // NullPointerException

실행 결과

오류가 아주 잘 떴다

arr는 배열 타입 변수이기 때문에 null로 초기화가 가능하고, 이 상태에서 arr[0]에 10을 저장하려고 하면 arr가 참조하는 배열 객체가 없기 때문에 NullPointerException이 발생한다.

 

String 타입

동일한 name1과 name2가 동일한 문자열을 참조할 경우 name1과 name2는 같은 힙 영역을 참조하므로 동일한 String 객체를 참조하게 된다.

String name1 = "최대한";
String name2 = "최대한";
System.out.println("name1 is equal to name2? = " + (name1==name2));

실행 결과

 

 

이를 방지하기 위해 new 연산자로 생성한다.

String name1 = new String("최대한");
String name2 = new String("최대한");
System.out.println("name1 is equal to name2? = " + (name1==name2));

실행 결과