1. 데이터 영역의 이해
자바의 메모리 공간은 Static(스태틱)영역, Stack(스택)영역, Heap(힙)영역으로 구분된다.
데이터 타입에 따라서 그에 맞는 공간에 할당되고 구동하는 방식 또한 서로 상이하다.
데이터 영역의 차이를 이해해 둔다면 추후 배울 배열, 메소드, 클래스를 정확하게 이해할 수 있다.
해당 데이터 영역의 이해는 앞으로 등장하는 각 항목의 설명하기 위해 정리하고 가지만, 예시 코드는 적어도 Chapter 17 이상으로 진행되어야 이해할 수 있다.
처음 보는 것이라면 글만 읽어보고 데이터 영역이 3개가 존재한다는 것만 인지하자.
2. Static area(스태틱 메모리 영역)
하나의 자바 파일은 크게 필드(field), 생성자(constructor), 메소드(method)로 구성된다.
그 중 필드 부분에서 선언된 변수(전역 변수)와 정적 멤버 변수(static이 붙은 자료형)는 Static 영역에 데이터를 저장한다.
Static 영역의 데이터는 프로그램의 시작부터 종료가 될 때까지 메모리에 남아있게 된다.
때문에 전역 변수가 어디서든 호출이 가능한 것이다.
package Example_static;
public class CardGame {
public static void main(String[] args) {
Card c = new Card();
c.kind="heart";
c.number=7;
Card c2 = new Card();
c2.kind="spade";
c2.number = 4;
System.out.println(c.width);
System.out.println(c.height);
c.width = 50;
c.height=80;
System.out.println(c2.width);
System.out.println(c2.height);
/* static은 다른 클래스, 메소드에서 호출할 때 동일한 static 데이터 영역에서 호출한다.
* 때문에 본래 참조형태은 Card 타입의 데이터인 width와 height를 변경하여도,
* 실제 데이터다 static에 있어 다른 곳에도 영향을 미친다.
* */
}
}
class Card
{
static int width = 100;
static int height = 250;
String kind;
int number;
}
3. Stack area(스택 메모리 영역)
메소드 내에서 정의하는 기본 자료형(int, double, byte, long, boolean 등)에 해당되는 지역 변수의 데이터 값이 저장되는 공간이다.
해당 메소드가 호출될 때 메모리에 할당되고 종료되면 메모리가 해제된다.
public class StackAreaEx {
public static void main(String[] args) {
int a = 5;
a = 4;
a = 3;
a = 2;
System.out.println(a);
for(int i=0; i<5; i++){ }// System.out.println(i); 컴파일 에러
}
}
위의 소스 코드에서 a라는 변수는 main 메소드가 호출될 때 Stack 영역에 할당되고 종료 시 해제된다.
a 라는 변수는 값이 5, 4, 3, 2 순으로 값을 할당 되었고, 최종적으로 출력되는 값은 2이다.
즉, Stack 영역은 Last In First Out의 구조를 갖고 있어 변수에 새로운 데이터가 할당되면 이전 데이터는 지워진다는 것이다.
또한 for문 내에 int i를 정의하였는데 for문이 종료된 다음 i를 출력하지 못하는 이유는 지역 변수이므로 for문의 종료와 함께 Stack 영역에서 해제되었기 때문이다.
4. Heap area (힙 메모리 영역)
참조형(Reference Type)의 데이터 타입을 갖는 객체 (인스턴스)와 배열 등은 Heap 영역에 데이터가 저장된다.
이때 변수 (객체, 객체 변수, 참조 변수)는 Stack 영역의 공간에서 Heap 영역의 참조값 (reference value, 메모리에 저장된 주소를 연결해주는 값인 해시코드)을 new 연산자를 통해 Return 받는다.
public class HeapAreaEx01 {
public static void main(String[] args) {
int[] a = null; // int형 배열 선언 및 Stack 영역 공간 할당
System.out.println(a); // 결과 : null
a = new int[5]; // Heap 영역에 5개의 연속된 공간 할당 및 변수 a에 참조값 할당
System.out.println(a); // 결과 : @15db9742 (참조값)
}
}
문자열을 저장하는 String도 참조형 타입의 변수이다.
new 연산자를 이용해서 생성하면 데이터가 Heap영역에 저장되며, 같은 값이라도 각각 다른 영역에 저장된다.
아래의 그림을 참고하면 String 변수의 데이터 저장과 출력을 조금 더 쉽게 이해할 수 있다.
public class HeapAreaEx02 {
public static void main(String[] args) {
String str1 = new String("dog");
String str2 = "dog";
String str3 = "dog";
if(str1 == str2){
System.out.println("같은 주소값 입니다.");
}else{
System.out.println("다른 주소값 입니다."); }
}
}
//출력: 다른 주소값 입니다.
참고로 Heap에 저장된 데이터가 더 이상 사용이 불필요하다면 메모리 관리를 위해 JVM(자바 가상머신)에 의해 알아서 해제된다.
해제됨에 따라 공간을 사용할 수 있도록 변경되며, 이러한 기능을 가비지 컬렉션(GC, 쓰레기 수집)이라고 한다.
(가비지 컬렉션 참고: 링크)
'Java > 기본 이론' 카테고리의 다른 글
[JAVA] Chapter 08. 정보를 출력하는 명령어 (0) | 2021.04.23 |
---|---|
[JAVA] Chapter 07. 연산자 (0) | 2021.04.23 |
[JAVA] Chapter 05. 변수 - 데이터 타입과 형변환 (0) | 2021.04.23 |
[JAVA] Chapter 04. 데이터의 기본이해 (0) | 2021.04.23 |
[JAVA] Chapter 03. 변수와 자바 기초 문법 (0) | 2021.04.22 |