본문 바로가기

Java

[Java] 메모리 영역과 Garbage Collection

Garbage Collection

대표적인 자바의 메모리 관리 방법 중 하나로 Heap 영역에서 동적 할당된 메모리 중 필요없게 된 메모리를 모아 주기적으로 제거하는 프로세스입니다.

메모리 영역

앞서 GCHeap 영역을 관리한다 했는데 그 영역이 무엇일까요?

자바 프로그램이 실행되면 JVM이 OS로 부터 메모리를 할당받고, 할당받은 메모리 영역을 여러영역으로 나누어 관리합니다.

메모리 영역에는 정적인 영역과 동적인영역 둘로 나눌 수 있습니다.

정적인 영역

Method 영역 또는 Static 영역이라고 불리우는 영역이 있습니다.

 

1. JVM이 동작해서 클래스가 로딩될 때 생성됩니다. 그리고 해당 영역의 데이터는 프로그램 시작부터 종료까지 메모리에 남아있습니다.

2. 읽어들인 클래스와 인터페이스에 대한 멤버 변수, 클래스 변수, Static, 상수, 생성자와 메소드를 저장하는 공간입니다.

3. Static 영역이라 불리는 만큼 이 영역은 어느곳에서나 접근이 가능합니다.

동적인 영역

동적인 영역에는 Stack 영역과 Heap 영역이 있습니다.

 

Stack 영역

 

해당 영역은 컴파일 타임 시 할당이 됩니다.

메소드와 관련한 영역인데요. 메소드가 호출될 때 메모리에 할당되고 종료되면 메모리에서 사라집니다.

해당 영역에는 Primitive 타입에 해당되는 지역변수, 매개변수, 리턴값 등이 저장됩니다.

당연히 Stack 영역이라 불리는 만큼 후입선출의 특성을 가지고있습니다.

또한 높은 메모리영역에서 낮은 메모리영역으로 메모리를 사용합니다.

 

 

Heap 영역

 

해당 영역은 런타임 시 할당이 됩니다. 

참조형 데이터 타입을 갖는 객체, 배열 등이 저장되는 공간입니다. ex) malloc, new ..

Heap 영역은 Stack 영역과 다르게 메모리 호출이 끝나도 삭제되지않고 유지됩니다.

이때 어떠한 참조변수도 참조하지 않게된다면 GC가 해당 변수를 메모리내에서 삭제하게됩니다.

또한 중요한 특징 중 하나는 Stack 영역은 스레드 개수마다 각각 생성되지만 Heap 영역은 무조건 단 하나의 영역만 존재합니다.

또한 낮은 메모리영역에서 높은 메모리영역으로 메모리를 사용합니다. Stack 영역과는 정 반대인데 이유는 모든 메모리 공간을 유용하게 사용하기 위해서입니다. 메모리를 사용하는 방향이 달라야 어느 한 영역은 메모리가 남는데 다른영역이 메모리가 다 떨어지는 상황을 모면합니다.

GC 동작과정

앞서 Heap 영역에대해 설명할 때 GC가 누구를 언제 삭제하는지에 대해 언급했습니다.

 

하지만 이 GC도 단점이 존재하는데 메모리가 언제 해제되는지 정확하게 알 수 없어 제어하기 힘들다는 점입니다.

GC가 동작할 때는 GC를 동작하는 스레드를 제외하곤 모든 스레드가 동작을 멈추기 때문에 오버헤드가 발생하기도 합니다.

 

Mark And Sweep

GC의 대상이 되는 객체를 식별(Mark)하고 제거(Sweep)하며 객체가 제거되어 파편화된 메모리영역을 앞에서부터 채워나가는 작업을 수행합니다.

 

Mark : 그래프 순회를 통해 연결된 객체들을 찾아내어 각각 어떤 객체를 참조하고 있는지 마킹합니다.

Sweep : 참조되지 않은 객체들을 Heap영역에서 제거합니다.

Compact : Sweep 후에 분산된 객체들을 Heap 시작 주소로 모아 메모리가 할당된 부분과 그렇지 않은 부분으로 압축합니다.

 

'Java' 카테고리의 다른 글

[Java] 멀티스레드와 동시성  (0) 2024.09.14
[Java] 자바의 Compiler  (1) 2024.09.08
[Java] Wrapper  (0) 2023.03.15
[Java] Optional  (0) 2023.03.15
[Java] JRE, JDK, JVM  (0) 2023.03.14