[Java] 메모리 : 스택(stack)영역과 힙(heap)영역
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 포스팅에서 다룰 예정 :)
끝!
(이 포스팅은 제 공부 복습용입니다. 틀린 부분이 있으면 과감하게 지적 해주세요!!)