[JAVA] Static, Stack, Heap

신명철·2022년 3월 4일
0

JAVA

목록 보기
4/14

1. Static Area (스태틱 메모리 영역 = Method Area)

static 키워드가 붙은 데이터를 저장하는 메모리 영역이다. 정적 메서드와 정적 변수를 합쳐서 정적 멤버라고 하는데, 정적 멤버는 객체에 소속된 멤버가 아니라 클래스에 고정된 멤버이다.

2. Stack Area (스택 메모리 영역)

메서드 내 정의하는 기본 자료형(int, double, byte, long, ...)에 해당되는 지역변수의 데이터 값이 저장되는 메모리 영역이다. 메서드가 호출될 때 생성되고 나갈 때 소멸된다는 특징이 있다.

기본형 타입의 경우 값이 저장되고 참조형 타입 변수는 참조값만 저장된다. 이 참조값(=인스턴스의 주소 값)은 Heap 영역에 있는 객체를 가르키는 역할을 한다.

Stack 영역 동작 예시

public void method(){
	int a = 2;
    a = operation(a);
}

public void operation(int param){
	int calc = param + 10;
    int result = calc + 100;
    return result;
}
  • Stack 영역에 a 라는 변수명이 할당되고 a 변수의 타입인 int 는 원시 타입이기 때문에 실제 2 라는 값이 할당된다.
  • a = operation() 가 동작하면 범위가 달라지기 때문에 기존의 a 값은 사용할 수 없게 된다.
  • operation() 의 지역변수인 calc = 12, result = 112, 매개변수인 param = 2 가 Stack 에 할당된다. 해당 변수들은 operation() 함수가 종료되면 stack 에서 pop 되어 소멸된다.
  • 지역변수들이 모두 사라지고 나면 스택에는 a = 112 만 남게 된다.

3. Heap Area (힙 메모리 영역)

참조형 데이터 타입을 갖는 객체, 배열 등의 데이터가 저장되는 메모리 영역이다. (new 연산자를 통해 생성된 객체)

Stack 영역의 공간의 변수(객체, 객체 변수, 참조 변수)는 실제 데이터가 저장된 Heap 영역의 주소 값을 new 연산자를 통해서 반환받는다.

객체의 실제 데이터는 Heap 영역에 올라간다.

즉, Heap 은 참조형 데이터 객체의 실제 데이터들이 담기는 공간이고, Static 영역의 객체는 Heap 영역의 참조 값이 갖게 된다.

Heap 영역 동작 예시

public class Main {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("test1");
        list.add("test2");

        print(list);
    }

    private static void print(List<String> listparam) {
        String value = listparam.get(0);
        listparam.add("test3");
        System.out.println(value);
    }
}
  • 먼저 List<String> list = new ArrayList<>(); 가 실행되면 new 연산자는 생성하려는 ArrayList 를 저장할 수 있는 공간이 Heap 에 있는지 확인한 다음 빈 ArrayList 를 참조하는 list 라는 지역변수를 스택에 할당한다.
  • 그 다음 add() 메서드들이 실행된다. 새롭게 생긴 문자열 test1, test2를 위한 변수는 스택에 할당되지 않고 ArrayList내부의 인덱스에 의해 하나씩 add()된 데이터에 대한 참조 값을 갖는다.
  • print(list) 가 실행되면 매개변수 listparamlist 의 참조 값을 그대로 갖게 된다. 그리고 print()함수 내부에서 list 는 scope 밖에 있게 되기 때문에 접근할수 없는 영역이 된다. (회색 표시)
  • print() 함수의 지역 변수 valuelistparam의 0번째 인덱스의 참조 값을 갖게 되고 print()는 새로운 데이터 test3을 추가한다.
  • print() 함수가 종료되면 listparam, value는 pop 되어 스택에서 사라지게 된다. ArrayList는 참조 타입이기 때문에 Heap 영역에 그대로 존재한다.

참고

profile
내 머릿속 지우개

0개의 댓글