๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

๋นˆ ๊ตฌ๋ฉ ์ฑ„์šฐ๊ธฐ

[Java] ์ฐธ์กฐ ๋„๋‹ฌ ๊ฐ€๋Šฅ์„ฑ reachability

์ถœ์ฒ˜

ChatGPT


์ž๋ฐ”์˜ ์ฐธ์กฐ ๋„๋‹ฌ ๊ฐ€๋Šฅ์„ฑ(reachability) ๊ฐœ๋…์€ Garbage Collection(GC) ๋งค์ปค๋‹ˆ์ฆ˜์˜ ํ•ต์‹ฌ์œผ๋กœ, ์ž๋ฐ” ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰ํ„ฐ๊ฐ€ ๊ฐ์ฒด๊ฐ€ ์—ฌ์ „ํžˆ "์‚ฌ์šฉ ์ค‘"์ธ์ง€, ์•„๋‹ˆ๋ฉด "๋” ์ด์ƒ ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” ์ƒํƒœ"์ธ์ง€ ๊ฒฐ์ •ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•˜๋Š” ์ค‘์š”ํ•œ ๊ธฐ์ค€์ด๋‹ค. ๋„๋‹ฌ ๊ฐ€๋Šฅ์„ฑ์€ ๊ฐ์ฒด๊ฐ€ ์—ฌ์ „ํžˆ ํ”„๋กœ๊ทธ๋žจ์˜ ์‹คํ–‰ ๊ฒฝ๋กœ ๋‚ด์—์„œ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•˜๊ณ , ์‚ฌ์šฉ๋  ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ๋Š”์ง€๋ฅผ ๋‚˜ํƒ€๋‚ธ๋‹ค.

 

1. ์ฐธ์กฐ ๋„๋‹ฌ ๊ฐ€๋Šฅ์„ฑ์ด๋ผ?

์ฐธ์กฐ ๋„๋‹ฌ ๊ฐ€๋Šฅ์„ฑ(reachability)์€ ํŠน์ • ๊ฐ์ฒด๊ฐ€ ํ”„๋กœ๊ทธ๋žจ์˜ ์–ด๋–ค ๋ถ€๋ถ„์—์„œ๋“  ์ ‘๊ทผ ๊ฐ€๋Šฅํ•˜๊ณ  ์‚ฌ์šฉ๋  ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ๋Š”์ง€๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๊ฐœ๋…์ด๋‹ค. ์ž๋ฐ” ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰ํ„ฐ๋Š” ํ”„๋กœ๊ทธ๋žจ ๋‚ด์˜ ๋ชจ๋“  ๊ฐ์ฒด๋ฅผ ๋Œ€์ƒ์œผ๋กœ ๋„๋‹ฌ ๊ฐ€๋Šฅ์„ฑ ๋ถ„์„(reachability analysis)์„ ์ˆ˜ํ–‰ํ•˜๋ฉฐ, ์ด ๋ถ„์„์— ๋”ฐ๋ผ ๊ฐ์ฒด์˜ ์ƒ๋ช…์ฃผ๊ธฐ๋ฅผ ๊ด€๋ฆฌํ•œ๋‹ค.

2. ๋„๋‹ฌ ๊ฐ€๋Šฅ์„ฑ์˜ ์œ ํ˜•

์ž๋ฐ”์—์„œ๋Š” ์ฐธ์กฐ ๋„๋‹ฌ ๊ฐ€๋Šฅ์„ฑ์— ๋”ฐ๋ผ ๊ฐ์ฒด์˜ ์ƒํƒœ๋ฅผ ์—ฌ๋Ÿฌ ๊ฐ€์ง€๋กœ ๋ถ„๋ฅ˜ํ•  ์ˆ˜ ์žˆ๋‹ค.

2.1 ๊ฐ•ํ•œ ์ฐธ์กฐ Strongly Reachable

์ •์˜

๊ฐ์ฒด๊ฐ€ ๊ฐ•ํ•œ ์ฐธ์กฐ(strong reference)์— ์˜ํ•ด ์ ‘๊ทผ ๊ฐ€๋Šฅํ•œ ๊ฒฝ์šฐ, ํ•ด๋‹น ๊ฐ์ฒด๋Š” ๊ฐ•ํ•˜๊ฒŒ ๋„๋‹ฌ ๊ฐ€๋Šฅํ•œ ์ƒํƒœ์ด๋‹ค.

์„ค๋ช…

๋งŒ์•ฝ ๊ฐ์ฒด์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒฝ๋กœ(reference chain)๊ฐ€ ์กด์žฌํ•˜๋ฉฐ, ๊ทธ ๊ฐ์ฒด๋Š” ๊ฐ•ํ•˜๊ฒŒ ๋„๋‹ฌ ๊ฐ€๋Šฅํ•œ ์ƒํƒœ์ด๋‹ค.

์˜ˆ์‹œ

๋กœ์ปฌ ๋ณ€์ˆ˜๋‚˜ ํด๋ž˜์Šค ํ•„๋“œ๊ฐ€ ํ•ด๋‹น ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ•˜๊ณ  ์žˆ์œผ๋ฉด, ์ด ๊ฐ์ฒด๋Š” ๊ฐ•ํ•˜๊ฒŒ ๋„๋‹ฌ ๊ฐ€๋Šฅํ•œ ์ƒํƒœ์ด๋‹ค.

Object obj = new Object(); // 'obj'๋Š” ๊ฐ•ํ•œ ์ฐธ์กฐ, 'new Object()'๋Š” ๊ฐ•ํ•˜๊ฒŒ ๋„๋‹ฌ ๊ฐ€๋Šฅ

 

2.2 ์•ฝํ•œ ์ฐธ์กฐ Weakly Reachable

์ •์˜

๊ฐ์ฒด๊ฐ€ ์•ฝํ•œ ์ฐธ์กฐ(weak reference)์— ์˜ํ•ด์„œ๋งŒ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•  ๋•Œ, ํ•ด๋‹น ๊ฐ์ฒด๋Š” ์•ฝํ•˜๊ฒŒ ๋„๋‹ฌ ๊ฐ€๋Šฅํ•œ ์ƒํƒœ์ด๋‹ค.

์„ค๋ช…

์•ฝํ•œ ์ฐธ์กฐ๋Š” ๊ฐ์ฒด์˜ ์ƒ๋ช…์ฃผ๊ธฐ์— ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š๋Š”๋‹ค. ์ฆ‰, ๊ฐ์ฒด๊ฐ€ ์•ฝํ•œ ์ฐธ์กฐ์—๋งŒ ์˜์กดํ•˜๋Š” ๊ฒฝ์šฐ, GC๋Š” ๊ฐ์ฒด๋ฅผ ์ˆ˜๊ฑฐ ๋Œ€์ƒ์œผ๋กœ ๊ฐ„์ฃผํ•œ๋‹ค.

์˜ˆ์‹œ

WeakReference๋กœ ์ฐธ์กฐ๋œ ๊ฐ์ฒด๋Š” ์•ฝํ•˜๊ฒŒ ๋„๋‹ฌ ๊ฐ€๋Šฅํ•˜๋ฉฐ, ๋‹ค๋ฅธ ๊ฐ•ํ•œ ์ฐธ์กฐ๊ฐ€ ์—†์„ ๋•Œ GC์˜ ๋Œ€์ƒ์ด ๋œ๋‹ค.

WeakReference<Object> weakRef = new WeakReference<>(new Object());
// weakRef๊ฐ€ ๊ฐ€๋ฆฌํ‚ค๋Š” ๊ฐ์ฒด๋Š” ์•ฝํ•˜๊ฒŒ ๋„๋‹ฌ ๊ฐ€๋Šฅ

 

2.3 ์œ ๋ น ์ฐธ์กฐ Phantomly Reachable

์ •์˜

๊ฐ์ฒด๊ฐ€ ์œ ๋ น ์ฐธ์กฐ(phantom reference)๋กœ๋งŒ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•œ ๊ฒฝ์šฐ, ํ•ด๋‹น ๊ฐ์ฒด๋Š” ์œ ๋ น ๋„๋‹ฌ ๊ฐ€๋Šฅ ์ƒํƒœ์ด๋‹ค.

์„ค๋ช…

์œ ๋ น ์ฐธ์กฐ๋Š” ๊ฐ์ฒด๊ฐ€ ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜์ด ์ˆ˜ํ–‰๋œ ํ›„์—๋„ ์ž”์กดํ•˜๋Š” ๊ฒฝ์šฐ๋ฅผ ๋‚˜ํƒ€๋‚ด๋ฉฐ, ๊ฐ์ฒด์˜ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ํ•ด์ œ๋˜๊ธฐ ์ „์— ์ถ”๊ฐ€ ์ž‘์—…์ด ์ˆ˜ํ–‰๋  ์ˆ˜ ์žˆ๋„๋ก ํ•œ๋‹ค. ์œ ๋ น ์ฐธ์กฐ๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ GC ์ดํ›„ ์ •๋ฆฌ(clean-up) ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋œ๋‹ค.

์˜ˆ์‹œ

PhantomReference๋กœ ์ฐธ์กฐ๋œ ๊ฐ์ฒด๋Š” ReferenceQueue์— ๋“ค์–ด๊ฐ€์„œ, ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ์‹ค์ œ๋กœ ํ•ด์ œ๋˜๊ธฐ ์ „์— ์ตœ์ข… ์ฒ˜๋ฆฌ๋ฅผ ํ•  ์ˆ˜ ์žˆ๋‹ค.

ReferenceQueue<Object> refQueue = new ReferenceQueue<>();
PhantomReference<Object> phantomRef = new PhantomReference<>(new Object(), refQueue);
// phantomRef๋Š” ์œ ๋ น ์ฐธ์กฐ๋กœ, ๊ฐ์ฒด๋Š” ์œ ๋ น ๋„๋‹ฌ ๊ฐ€๋Šฅ ์ƒํƒœ

2.4 ์ข…๋‹จ ์ฐธ์กฐ Finally Reachable

์ •์˜

๊ฐ์ฒด๊ฐ€ ์ข…๋‹จ ์ฐธ์กฐ(finally reference)๋กœ๋งŒ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•œ ๊ฒฝ์šฐ์ด๋‹ค.

์„ค๋ช…

๊ฐ์ฒด๊ฐ€ ์ฐธ์กฐ๋˜์ง€๋Š” ์•Š์ง€๋งŒ, finalize() ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋Š” ์ƒํƒœ์ด๋‹ค. ์ด๋Ÿฌํ•œ ๊ฐ์ฒด๋Š” finalize() ๋ฉ”์†Œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋œ ํ›„์—๋„ ํšŒ์ˆ˜๋˜์ง€ ์•Š์œผ๋ฉฐ ๋‹ค์Œ GC์—์„œ ์ œ๊ฑฐ๋œ๋‹ค.

์˜ˆ์‹œ

๊ฐ์ฒด๊ฐ€ ์ข…๋‹จ ๋„๋‹ฌ ๊ฐ€๋Šฅ ์ƒํƒœ์— ๋„๋‹ฌํ•˜๋ฉด, GC๋Š” ๊ฐ์ฒด์˜ finalize() ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์ •๋ฆฌ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.

class MyClass {
    @Override
    protected void finalize() throws Throwable {
        System.out.println("Finalize called!");
    }
}

MyClass obj = new MyClass();
obj = null; // ์ด์ œ ๊ฐ์ฒด๋Š” ๊ฐ•ํ•˜๊ฒŒ ๋„๋‹ฌ ๊ฐ€๋Šฅํ•˜์ง€ ์•Š์Œ, ์ข…๋‹จ ๋„๋‹ฌ ๊ฐ€๋Šฅ ์ƒํƒœ๋กœ ์ „ํ™˜๋  ์ˆ˜ ์žˆ์Œ

 

3. ์ฐธ์กฐ ๋„๋‹ฌ ๊ฐ€๋Šฅ์„ฑ ๋ถ„์„ ๊ณผ์ •

์ž๋ฐ”์˜ ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰ํ„ฐ๋Š” ๋„๋‹ฌ ๊ฐ€๋Šฅ์„ฑ ๋ถ„์„์„ ํ†ตํ•ด ๊ฐ์ฒด๊ฐ€ ์—ฌ์ „ํžˆ ์‚ฌ์šฉ ์ค‘์ธ์ง€ ์•„๋‹ˆ๋ฉด ์ˆ˜์ง‘ ๋Œ€์ƒ์ธ์ง€ ๊ฒฐ์ •ํ•œ๋‹ค. ์ด ๊ณผ์ •์€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋‹จ๊ณ„๋กœ ์ด๋ฃจ์–ด์ง„๋‹ค.

1. ๋ฃจํŠธ ์ง‘ํ•ฉ(Root Set) ์‹๋ณ„

๋ฃจํŠธ ์ง‘ํ•ฉ์€ ๊ฐ์ฒด ๋„๋‹ฌ ๊ฐ€๋Šฅ์„ฑ ๋ถ„์„์˜ ์‹œ์ž‘ ์ง€์ ์œผ๋กœ, ํ”„๋กœ๊ทธ๋žจ์—์„œ ์ง์ ‘์ ์œผ๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ๋ชจ๋“  ์ฐธ์กฐ๋ฅผ ํฌํ•จํ•œ๋‹ค.

์ผ๋ฐ˜์ ์œผ๋กœ ๋ฃจํŠธ ์ง‘ํ•ฉ์—๋Š” ๋‹ค์Œ์ด ํฌํ•จ๋œ๋‹ค.

  • ์Šคํƒ(stack) ๋ณ€์ˆ˜ : ํ˜„์žฌ ๋ฉ”์†Œ๋“œ ํ˜ธ์ถœ ์Šคํƒ์— ์žˆ๋Š” ๋ชจ๋“  ์ง€์—ญ ๋ณ€์ˆ˜์™€ ๋งค๊ฐœ๋ณ€์ˆ˜
  • ์ •์  ๋ณ€์ˆ˜(static fields) : ํด๋ž˜์Šค ๋กœ๋”์—์„œ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•œ ๋ชจ๋“  ์ •์  ํ•„๋“œ
  • JNI ์ฐธ์กฐ : Java Native Interface๋ฅผ ํ†ตํ•ด ๋„ค์ดํ‹ฐ๋ธŒ ์ฝ”๋“œ๊ฐ€ ์ฐธ์กฐํ•˜๊ณ  ์žˆ๋Š” ๊ฐ์ฒด

2. ๊ฐ์ฒด ๊ทธ๋ž˜ํ”„ ํƒ์ƒ‰

๋ฃจํŠธ ์ง‘ํ•ฉ์—์„œ ์‹œ์ž‘ํ•ด ๋ชจ๋“  ๊ฐ์ฒด์˜ ์ฐธ์กฐ ๊ด€๊ณ„๋ฅผ ๋”ฐ๋ผ๊ฐ€๋ฉฐ, ๋„๋‹ฌ ๊ฐ€๋Šฅํ•œ ๋ชจ๋“  ๊ฐ์ฒด๋ฅผ ํƒ์ƒ‰ํ•œ๋‹ค.

๊ฐ ๊ฐ์ฒด๊ฐ€ ๋„๋‹ฌ ๊ฐ€๋Šฅ ์—ฌ๋ถ€๋ฅผ ํŒ๋‹จํ•˜๊ธฐ ์œ„ํ•ด, GC๋Š” ์ฐธ์กฐ ๊ทธ๋ž˜ํ”„(reference graph)๋ฅผ ํ™œ์šฉํ•ด ๊ฐ์ฒด ๊ฐ„์˜ ์—ฐ๊ฒฐ์„ ์ถ”์ ํ•œ๋‹ค.

3. ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜ ๋Œ€์ƒ ์‹๋ณ„

์ฐธ์กฐ ๊ทธ๋ž˜ํ”„๋ฅผ ํ†ตํ•ด ๋„๋‹ฌํ•  ์ˆ˜ ์—†๋Š”(unreachable) ์ƒํƒœ๋กœ ํŒ๋ช…๋œ ๊ฐ์ฒด๋“ค์€ ๋” ์ด์ƒ ํ”„๋กœ๊ทธ๋žจ์— ์˜ํ•ด ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” ๊ฒƒ์œผ๋กœ ๊ฐ„์ฃผ์™ธ๋” ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜ ๋Œ€์ƒ์ด ๋œ๋‹ค.

 

4. ์ˆœํ™˜ ์ฐธ์กฐ์™€ Garbage Collection

์ž๋ฐ”์˜ ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰ํ„ฐ๋Š” ์ฐธ์กฐ ๋„๋‹ฌ ๊ฐ€๋Šฅ์„ฑ์— ๊ธฐ๋ฐ˜ํ•ด ๊ฐ์ฒด๋ฅผ ์ˆ˜์ง‘ํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ์ˆœํ™˜ ์ฐธ์กฐ(circular reference)๋กœ ์ธํ•œ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๋Š” ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š”๋‹ค. ์ˆœํ™˜ ์ฐธ์กฐ๋ž€ ๋‘ ๊ฐœ ์ด์ƒ์˜ ๊ฐ์ฒด๊ฐ€ ์„œ๋กœ๋ฅผ ์ฐธ์กฐํ•˜๊ณ  ์žˆ๋Š” ์ƒํƒœ๋ฅผ ์˜๋ฏธํ•œ๋‹ค.

 

์ˆœํ™˜ ์ฐธ์กฐ์˜ ์˜ˆ

class A {
    B b;
}

class B {
    A a;
}

A a = new A();
B b = new B();
a.b = b;
b.a = a;

a = null;  // a๊ฐ€ ์ฐธ์กฐํ•˜๋Š” A ๊ฐ์ฒด๋Š” ๋” ์ด์ƒ ๊ฐ•ํ•œ ์ฐธ์กฐ๋ฅผ ๋ฐ›์ง€ ์•Š์Œ
b = null;  // b๊ฐ€ ์ฐธ์กฐํ•˜๋Š” B ๊ฐ์ฒด๋„ ๋” ์ด์ƒ ๊ฐ•ํ•œ ์ฐธ์กฐ๋ฅผ ๋ฐ›์ง€ ์•Š์Œ

 

์œ„ ์˜ˆ์ œ์—์„œ A ๊ฐ์ฒด์™€ B ๊ฐ์ฒด๋Š” ์„œ๋กœ๋ฅผ ์ฐธ์กฐํ•˜๊ณ  ์žˆ์ง€๋งŒ, a์™€ b ๋ณ€์ˆ˜๊ฐ€ ๋ชจ๋‘ null๋กœ ์„ค์ •๋˜๋ฉด ๋” ์ด์ƒ ๊ฐ•ํ•œ์ฐธ์กฐ๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š๋Š”๋‹ค. GC๋Š” ๋‘ ๊ฐ์ฒด๊ฐ€ ์„œ๋กœ๋ฅผ ์ฐธ์กฐํ•˜๊ณ  ์žˆ์–ด๋„, ์™ธ๋ถ€์—์„œ ๋„๋‹ฌํ•  ์ˆ˜ ์—†๋‹ค๋Š” ์ ์„ ํ™•์ธํ•˜๊ณ  ์ˆ˜์ง‘ ๋Œ€์ƒ์— ํฌํ•จ์‹œํ‚จ๋‹ค.

 

5. ๊ฒฐ๋ก 

์ฐธ์กฐ ๋„๋‹ฌ ๊ฐ€๋Šฅ์„ฑ(reachability)์€ ์ž๋ฐ”์˜ GC๊ฐ€ ๊ฐ์ฒด๋ฅผ ์ˆ˜์ง‘ํ• ์ง€ ์—ฌ๋ถ€๋ฅผ ๊ฒฐ์ •ํ•˜๋Š” ์ค‘์š”ํ•œ ๊ธฐ์ค€์ด๋‹ค. ๋„๋‹ฌ ๊ฐ€๋Šฅ์„ฑ ๋ถ„์„์„ ํ†ตํ•ด ํ”„๋กœ๊ทธ๋žจ์ด ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ฐ์ฒด๋ฅผ ์‹๋ณ„ํ•˜๊ณ , ์ด๋Ÿฌํ•œ ๊ฐ์ฒด๋ฅผ ์ž๋™์œผ๋กœ ๋ฉ”๋ชจ๋ฆฌ์—์„œ ์ œ๊ฑฐํ•˜์—ฌ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๋ฅผ ๋ฐฉ์ง€ํ•œ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ํ”„๋กœ๊ทธ๋ž˜๋จธ๋Š” ์—ฌ์ „ํžˆ ๋ถˆํ•„์š”ํ•œ ์ฐธ์กฐ๋ฅผ ์ตœ์†Œํ™”ํ•˜๊ณ , ๊ฐ์ฒด๊ฐ€ ๋” ์ด์ƒ ํ•„์š”ํ•˜์ง€ ์•Šใ…‡๋ฅด ๋•Œ ๋ช…์‹œ์ ์œผ๋กœ ์ฐธ์กฐ๋ฅผ ์ œ๊ฑฐํ•˜๋Š” ๋“ฑ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ์— ์‹ ๊ฒฝ ์จ์•ผ ํ•œ๋‹ค. GC๋Š” ๊ฐ•๋ ฅํ•œ ๋„๊ตฌ์ด์ง€๋งŒ, ์˜ฌ๋ฐ”๋ฅธ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ ๊ธฐ๋ฒ•๊ณผ ๊ฒฐํ•ฉํ•ด ์‚ฌ์šฉํ•ด์•ผ ์ตœ์ƒ์˜ ๊ฒฐ๊ณผ๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค.