JAVA

[ Java ] - 변수의 타입(기본형 / 참조형) * 자바메모리 구조

algml0703 2022. 12. 25. 08:42
반응형

  변수의 타입

변수는 값이 저장되어 있는 메모리 공간을 의미한다. 

자바에서 변수 타입은 기본적으로 기본형과 참조형으로 구분되는데, 기본형은 변수의 메모리 공간에 값 자체가 할당되는 것이며, 참조형은 변수의 메모리 공간에 해당 값이 저장된 주소가 저장된다. 

* 상수
한 번 값을 할당한 후 다른 값을 할당할 수 없는 변수를 의미한다. 상수는 값의 재할당이 불가능하기 때문에 기본적으로 변수의 선언과 함께 값의 초기화가 이루어져야 한다. 상수로 선언한기 위해서는 변수의 타입 앞에 final을 붙여주면 된다. 

 

기본형 (primitive type)

기본형 타입으로는 문자형(char), 숫자형(byte, short, int, long), 실수형(float, double), 논리형(boolean)이 있으며, 변수 메모리 공간에 값(data) 자체가 저장된다.

- 논리형 : boolean (1 byte)
- 문자형 : char(2 byte) ~ char은 단 하나의 문자만 저장이 가능하다.(문자형 변수에 실제 문자가 저장되는 것이 아니라 해당 문자의 유니코드인 정수가 저장된다.) 문자열 저장은 참조형 타입인 String을 사용한다.
- 정수형 : byte(1 byte), short(2 byte), int(4 byte), long(8 byte)
- 실수형 : float(4 byte), double(8 byte)

* 1byte = 8bit
1bit 는 컴퓨터가 값을 저장하는 최소 단위이고, 1byte는 데이터의 기본 단위이다.
또한 word는 cpu가 한 번에 처리가능한 데이터의 크기를 의미하며, 32 bit cpu에서는 32bit( 즉 4 byte), 64bit cpu에서는 64bit (즉 8 byte) 크기의 데이터가 한 번에 처리가능하다.

참조형 (reference type)

참조형은 기본형 이외의 타입을 의미하며, 실제 값은 별도의 메모리 공간에 저장되고, 변수의 메모리 공간에는 해당 값이 할당된 주소값(memory address)이 저장된다.


* 자바 메모리 구조

 heap                                                        

new를 통해 생성된 모든 인스턴스가 저장되는 공간이다. 인스턴스는 결국 참조형(reference type) 데이터 타입임을 의미하는데, 참조형으로 선언된 변수의 값은 heap 메모리 공간에 할당된다. (참조형 데이터 타입의 값 자체는 heap 메모리 공간에, 해당 값의 주소는 stack영역에 저장된다.)
heap 영역의 메모리는 가비지 컬렉터(Garbage Collector)를 통해 관리되며, 참조되지 않는 경우에는 해당 공간에 할당된 메모리가 해제된다. (때문에 개발자는 메모리 관리를 신경쓸 필요가 없다.)

 static (=method 영역)                             

전역변수와 static이 붙은 클래스 메서드의 경우에 static 영역에 할당되어, 프로그램의 시작부터 종료까지 메모리에 유지되며, 프로그램이 종료되는 때에 메모리에서 해제된다. static 메모리가 차지하는 공간은 프로그램 로드시에 결정되기 때문에, 프로그램 컴파일 시간에 많은 영향을 준다. static으로 선언된 경우 프로그램 전체에서 공유된다. import 하여 사용하는 패키지 파일들도 static 영역에 저장된다.

* 클래스 메서드나 클래스 변수의 경우 인스턴스를 생성하지 않고, 클래스명.메서드명 또는 클래스명.변수명 이와 같은 식으로 사용한다.

 stack (call stack 또는 execution stack) 

지역변수와 일반 메서드가 저장되는 공간이다. 기본형의 경우 값 자체가 stack 영역에 할당되고, 참조형 타입의 값을 지역 변수에 할당 시, stack 메모리 공간에 실질적으로 할당되는 것은 heap 메모리 공간에 저장된 값의 참조값(=주소값)이다.
메서드의 경우는 메서드가 호출될 때 메모리에 할당되고, 해당 메서드가 종료되면 메모리에서 해제된다. 
stack 영역은 LIFO(=Last In First Out) 구조로 되어 있다. 

* 흔히 말하는 스택오버플로우란 재귀호출이나, 무한반복을 하는 for문이나 while문이 실행되어 함수가 실행되지 않고, 계속해서 스택에 메모리가 쌓이게 되는 경우 스택 메모리가 감당할 수 있는 범위를 초과하는 경우 발생하는 에러를 의미한다.

* LIFO 구조란

package chapter06;

public class CallStackTest {
    public static void main(String args[]) {
        System.out.println("main(String[] args)실행됨");
        firstMethod();
        System.out.println("main(String[] args)종료됨");
    }

    static void firstMethod () {
        System.out.println("firstMethod 실행됨");
        secondMethod();
        System.out.println("firstMethod 실행됨");
    }

    static void secondMethod () {
        System.out.println("secondMethod 실행됨");
        System.out.println("secondMethods 실행됨");
    }
}
//    출력 순서 -----------------
//    main(String[] args)실행됨
//    firstMethod 실행됨
//    secondMethod 실행됨
//    secondMethods 실행됨
//    firstMethod 실행됨
//    main(String[] args)종료됨

LIFO구조란 Last In First Out 의 약어로 후입선출 즉 가장 마지막 항목이 가장 먼저 제거됨을 의미한다. 위의 클래스를 보면 가장 먼저 main 메서드가 실행되어 스택 메모리에 가장 먼저 올라가고, 그 위에 firstMethod 메서드가 main 메서드 위에 올라가고, firstMethod 메서드 위에 secondMethod 메서드 위에 올라가게 된다. 메모리에서 제거될 때는 메모리에 올라간 순서와 반대로 마지막에 올라간 secondMethod 메서드가 모든 실행을 끝내고 제거되고, 그 뒤로는 firstMethod, main 메서드 순으로 실행이 완료되고 메모리에서 제거된다.

 


 

출처

자바의 정석(책- 남궁 성 지음)

 

 

 

반응형