본문 바로가기

ETC

자바에서 스택과 힙

0. 개요

- Java의 메모리 관리

- 스택과 힙 영역

- Wrapper 클래스와 Immutable Object

- Garbage Collection

 

 

1. 자바의 메모리 관리 

 

자바에서 스택 영역에 할당되는 데이터는 다음과 같다. 

- 원시 타입 데이터 : 데이터 값이 저장된다. byte, short, int, long, double, float, boolean, char

- 참조 타입 변수 : Heap 영역에 생성된 Object 타입 데이터들의 참조 값이 저장된다. 

 

또한 스택 영역에는 지역 변수들이 할당되며 scope에 따른 visibility를 가진다. 

- 스택 메모리의 top에 존재하는 하나의 스택 프레임만 활성화되어 그 이전에 존재하는 스택 프레임은 모두 비활성화된다.

- 즉, 비활성화된 스택 프레임의 지역 변수에 접근이 불가능하다. 

- 스택 프레임은 매개변수, 지역변수, 반환 주소값, 반환 값이다. 함수가 실행되는 동안 오직 해당 스택 프레임에만 접근이 가능하기 때문에 scope가 한정된다. 함수가 종료되면 해당 scope 만큼의 스택 프레임이 pop 이되며 반환 주소값 위치로 돌아간다.

 

스택 메모리 영역은 스레드 별로 할당된다. 

- 스레드가 시작될 때 스택 메모리가 생성되며 각각의 스레드는 각각의 스택 메모리를 가진다. 

- 오직 자신만의 스택 영역에만 접근할 수 있습니다. 

 

 

자바에서 힙 영역에 저장되는 데이터는 다음과 같다.

- 모든 Object 타입 데이터 : Integer, String, ArrayList,,,

- 힙 영역의 Object 객체들을 참조하는 변수들을 스택 영역에 저장한다. 

 

스택 영역과 달리 힙 영역은 몇 개의 스레드가 존재하든 상관 없이 단 하나의 힙 영역만 존재한다. 

자바에서 new 키워드는 Object 객체를 저장할 수 있는 충분한 힙 공간을 확인한 다음 할당하며 해당 공간을 참조할 변수에 주소값을 전달한다. 

함수 내부로 전달받은 파라미터는 종료 시점에서 사라지지만 해당 파라미터가 참조하고 있는 객체는 여전히 힙 영역에서 남아 있기 때문에 변경 내역이 반영 된다.

 

단 불변 객체의 경우 (Immutable) 연산을 수행할 때 기존 오브젝트를 변경하는 것이 아닌 새로운 오브젝트를 생성한다. 

 

자바에서 Wrapper Class로 분류되는 Integer, Character, Byte, Boolean, Long, Double, Float, Short 클래스는 모두 Immutable이므로 힙 영역에서 같은 Object를 참조하고 있더라도 새로운 연산이 적용되는 순간 새로운 Object로 힙에 할당된다. 

 

Integer 클래스 내부에 값이 저장되는 value 변수는 private final int value로 선언되어 생성자에의해 생성된 순간에만 초기화되고 그 이후로는 변경 불가능하다. 

( 클래스에 붙은 final 키워드의 경우엔 상속을 제한하는 의미를 지니고 있다. )

 

 

2. Garbage Collection 

public class Main{
    public static void main(String[] args) {
        String url = "http://"
        url += "localhost:8080:
    }
}

스택 영역에 저장 되고 있는 url 은 불변 객체인 String으로 생성한 힙 영역의 객체를 참조할 주소 데이터를 지니고 있다.

새로운 String 데이터인 "localhost:8080"이 힙 영역에 할당되고 url이 참조하고 있는 문자열 데이터와 += 연산을 수행할 때를 살펴 보겠다.

url이 참조하고 있던 문자열 데이터에 "localhost:8080"이 더해지는 것이 아닌  새로 복사하고 새로 할당한 "http://" 데이터에 "localhost:8080" 이 더해진다. 

 

따라서 연산이 수행된 이후 스택 영역에서 어떠한 데이터도 기존의 "http://" 데이터를 참조하고 있지 않다. 

기존의 "http://" 문자열을 참조하고 있는 변수가 아무 것도 없다 하여 Unreachable 오브젝트라고 한다.

 

JVM의 Garbage Collector는 Unreachable Object를 우선적으로 메모리에서 제거하여 공간을 확보한다.

Unreachablel Object는 스택 영역에서 도달할 수 없는 힙 영역의 객체를 의미한다. 

 

Garbage Collection 과정은 Mark and Sweep 이라고도 한다. 

스택의 모든 변수를 스캔하여 각각이 어떤 오브젝트를 레퍼런스 하는지 찾는 과정을 Mark라고 하고 한다. Reachable 오브젝트가 참조하고 있는 오브젝트 역시 Marking 한다.

 

Marking 작업 동안 모든 스레드는 중단된다. 이를 stop the world라고 한다. 

 

mark 되지 않은 모든 오브젝트들을 힙에서 제거하는 과정을 Sweep 라고 한다. 

 

 

3. 참고

https://yaboong.github.io/java/2018/05/26/java-memory-management/

 

자바 메모리 관리 - 스택 & 힙

개요 Java 에서 메모리 관리는 어떻게 이루어지는지 알아보기 위함. Stack 과 Heap 영역 각 역할에 대해 알아본다. 간단한 코드예제와 함께 실제 코드에서 어떻게 Stack 과 Heap 영역이 사용되는지 살펴

yaboong.github.io

 

'ETC' 카테고리의 다른 글

기술면접 대비  (0) 2023.05.12
프로세스와 스레드  (0) 2023.05.12
메모리의 구조  (0) 2023.05.12
오버헤드, 스택 오버 플로우  (1) 2023.05.12
[SQL] 일단 시작해보기 - 가장 자주 쓰는 DML 위주  (0) 2023.04.29