안녕하세요 열코입니다.

이번시간에는 자바의 가비지 컬렉션에 대해 알아보겠습니다.


우리가 C/C++ 프로그래밍을 할 때 메모리 누수(Memory Leak)를 막기 위해 객체를 생성한 후 

사용하지 않는 객체를 파괴(메모리 해제)를 프로그래머가 직접 해주어야 했습니다.


하지만 Java에서는 JVM(Java Virtual Machine)이 구성된 JRE(Java Runtime Environment)가 

제공되며 JVM 구성 요소 중 하나인 가비지 컬렉션(Garbage Collection)이 자동으로 

사용하지 않는 객체를 파괴합니다.


JVM의 가비지 컬렉션은 다음과 같은 단계로 메모리 해제 작업을 수행합니다.

1. 마킹 작업 : 사용중인 메모리와 사용 하지않는 메모리를 식별합니다.

2. 일반 삭제 : 참조되지 않는 객체를 제거하고 빈 공간에 대한 포인터를 남겨둡니다.

+ 압축 삭제 : 삭제 된 객체 외 나머지 객체를 메모리 공간을 효율적으로 사용하며 삭제


또한 JVM의 가비지 컬렉션은 객체들을 세대로 나누어 처리합니다.

- 젊은 세대 : 새로운 모든 객체를 할당하는 곳입니다. 젊은 세대가 가득차면 가비지 컬렉션을 수행하며 

매우 빠른 속도로 진행됩니다. 사소한(가벼운) 가비지 컬렉션이 수행됩니다.

- 이전 세대 : 오랫동안 생존한 객체를 저장합니다. 젊은 세대에서 생성된 객체에 임계 값을 주어지고 어느정도

연령에 도달하면 이전 세대로 이동합니다. 이전 세대의 객체를 수집하는 것을 주요 가비지 컬렉션이라고 합니다.


세대 별 가비지 컬렉션은 다음과 같은 과정으로 수행됩니다.

1. 새로운 객체는 에덴(Eden) 공간에 할당되며, 그 외 두 개의 생존 공간이 모두 비어있는 상태입니다.

2. 에덴 공간이 가득차게 되면 사소한(가벼운) 가비지 컬렉션이 시작됩니다.

3. 참조된 객체는 첫번째 생존 공간으로 이동되며 참조되지 않는 객체는 모두 삭제됩니다.

4. 가비지 컬렉션이 수행되는 동안 첫번째 생존 공간의 객체들은 특정 임계값이 넘어가면 두번째 생존 공간으로 이동합니다.

5. 두 번째 생존 공간의 객체들도 특정 임계값이 넘어가면 이전 세대로 넘어가게 됩니다.

6. 이전 세대의 객체가 일정 크기 이상 수집되면 주요 가비지 컬렉션이 수행됩니다.


또한 다음과 같이 JVM에게 가비지 컬렉션을 실행하도록 요청할 수 있습니다.

System.gc() 메소드 또는 Runtime.getRuntime().gc() 메소드 사용 (수행되는 가비지 컬렉션은 동일합니다.)



아래는 객체를 가비지 컬렉션의 대상으로 만드는 방법입니다.

1. 메소드 내부에서 생성된 객체

class GCTest {

String name;

public GCTest(String name) {

this.name = name;

}


static void show() {

GCTest gct1 = new GCTest("gct1");

show2();

}

static void show2() {

GCTest gct2 = new GCTest("gct2");

}


public static void main(String[] args) {

show();

System.gc(); //  gct1과 gct2는 가비지 컬렉션의 대상이 됨.

}

}

위 코드와 같이 메소드가 호출된 후 내부에 일부 객체가 만들어지고 메소드가 종료됬을 때, 메소드 내부의 객체들은

익명이 되어 가비지 컬렉션의 대상이 됩니다.


2. 참조 변수 재 지정

Class GCTest {

String name;

public GCTest(String name) {

this.name = name;

}


public static void main(String[] args) {

GCTest gct1 = new GCTest("gct1");

GCTest gct2 = new GCTest("gct2");


gct1 = gct2;


System.gc();

}

}

위 코드는 한 객체의 참조가 다른 객체를 참조할 때 이전 객체는 더 이상 참조를 갖지 못해 가비지 컬렉션의 대상이 됩니다.


3. 참조 변수 무효화

Class GCTest {

String name;

public GCTest(String name) {

this.name = name;

}


public static void main(String[] args) {

GCTest gct1 = new GCTest("gct1");


gct1 = null;


System.gc();

}

}

위 코드는 객체의 참조 변수가 null로 변경되었기 때문에 가비지 컬렉션의 대상이 됩니다.



4. 익명 객체

Class GCTest {

String name;

public GCTest(String name) {

this.name = name;

}


public static void main(String[] args) {

new GCTest("gct1");


System.gc();

}

}

익명 객체의 참조는 어느곳에도 저장되지 않기 때문에 가비지 컬렉션의 대상이 됩니다.



이상 '자바 가비지 컬렉션'에 대해 알아보았습니다.

질문 또는 오타나 잘못된 정보가 있는 경우 댓글로 달아주세요!

공감♡ 버튼을 눌러주시면 더욱 유용하고 좋은 포스팅으로 찾아 뵙겠습니다.




to Top