Java+Spring Boot

[Java] 메모리 : 스택(stack)영역과 힙(heap)영역

노력형 천재 호소인 2023. 6. 2. 02:09

1. 데이터 타입과 메모리 영역

자바의 데이터 타입은 primitive type과 reference type으로 분류된다.

자바 데이터 타입 (출처 : 이것이 자바다)

primitive 타입과 reference 타입의 가장 큰 차이점은 다음과 같다.

 

int age = 30;
char ch = 'a';

String name = "김현수";
String language = "Java";

위와 같이 변수를 선언하고 초기화 했을 때, primitive 타입인 age와 ch 는 초기화 한 값인 30과 'a' 가 각각 스택영역에 값 그대로 저장된다.

 

반면, reference 타입인 String은 스택영역에 초기화 된 값 "김현수", "Java" 가 저장되는 것이 아니라, String 객체가 heap영역에 만들어져 그 객체에 "김현수", "Java"를 담고, 그 객체의 주소가 스택영역에 변수명과 함께 저장된다. 

악필...

  • 메소드 영역 : 바이트코드 파일을 읽은 내용이 저장되는 영역. 클래스별로 상수, 필드, 메서드코드, 생성자코드 등이 저장된다. 
  • Heap 영역 : 객체가 생성되는 영역이다. 객체의 주소는 메소드 영역과 스택 영역에서 참조할 수 있다.
  • Stack 영역 : 메소드를 호출할 때 생성되는 프레임이 저장되는 영역이다. 메소드 호출이 끝나면 프레임은 자동 제거된다. 프레임 내부에는 로컬 변수 스택이 있는데, 여기에서 기본 타입 변수와 참조 타입 변수가 생성되고 제거된다.

메모리 영역의 구성 (출처 : 이것이 자바다)


2. Reference 타입 변수의 == , != 연산

== , != 연산은 변수의 값이 같고 다름을 비교하는 연산자이다. primitive 타입의 데이터를 비교하는 것은 이미 익숙하다.

int a = 10;
int b = 10;
int c = 20;

System.out.println(a == b);	//true
System.out.println(a == c);	//false

stack영역에 대해 배운 상황에서 다음과 같이 이해할 수 있다. 동등연산자는 결국 stack영역에 저장된 값을 비교하는 연산자다. 

그렇다면 reference 타입의 데이터는 변수의 값이 아닌 객체의 주소를 stack영역에 저장하므로 동등연산자가 변수의 객체 주소를 비교하게 되는것이다. 

(이제부터 [주소] 라는 명칭대신 [참조값] 이라는 명칭을 쓰겠음)

int[] arr1 = new int[]{1, 2, 3};
int[] arr2 = arr1;
int[] arr3 = new int[]{1, 2, 3};

System.out.println(arr1 == arr2);	//true
System.out.println(arr1 == arr3);	//false
System.out.println(arr1 != arr3);	//true

배열은 reference 타입이므로 stack영역에 참조값을 저장한다. arr2에 arr1을 대입했으므로 참조값이 같아서 첫번째는 true.

arr1과 arr3은 같은 배열을 갖지만, 객체가 서로 다르므로 참조값이 달라서 두번째는 false, 세번째는 true이다.

 

2-a. 조금 특별한 타입 : String

마찬가지로 reference 타입인 String 객체를 보자.

String name1 = "현수";
String name2 = name1;
String name3 = "현수";

System.out.println(name1 == name2);	//true
System.out.println(name1 == name3);	//true
System.out.println(name1 != name3);	//false

name2 에 그대로 name1을 초기화 시켰으므로 참조값이 같으므로 name1==name2 는 true이다.

name1과 name3 은 값이 "현수"로 같지만, 서로 다른 객체이므로 참조값이 다를테고, 두번째는 false 세번째는 true가 나와야하는데 ..! 그렇지 않다. 두번째는 true, 세번째는 false가 나온다. 

 

사실 위 결과는 String 타입이 갖는 특이한 성질 때문에 나온것이다. 이 부분은 String 포스팅에서 다룰 예정 :)

 

끝!

 

(이 포스팅은 제 공부 복습용입니다. 틀린 부분이 있으면 과감하게 지적 해주세요!!)