์ถ์ฒ
ChatGPT
์๋ฐ์์๋ ๋ค์ํ ์ฐธ์กฐ ํ์ ์ ์ ๊ณตํด, ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ์ ๊ฐ๋น์ง ์ปฌ๋ ์ (GC)์ ๋ ์ธ๋ฐํ๊ฒ ์ ์ดํ ์ ์๊ฒ ํ๋ค. ๊ฐ๊ฐ์ ์ฐธ์กฐ ํ์ ์ ๊ฐ์ฒด์ ์๋ช ์ฃผ๊ธฐ์ ๋ฉ๋ชจ๋ฆฌ ์์ง ์ ๋ต์ ๋ค๋ฅด๊ฒ ๊ด๋ฆฌํ๋๋ก ๋๋๋ค. ์๋ฐ๋ ๊ฐํ ์ฐธ์กฐ(Strong Reference)์ธ์๋ ์ฝํ ์ฐธ์กฐ(Weak Reference), ๋ถ๋๋ฌ์ด ์ฐธ์กฐ(Soft Reference) ๊ทธ๋ฆฌ๊ณ ์ ๋ น ์ฐธ์กฐ(Phantom Reference)๋ฅผ ์ ๊ณตํ๋ค. ์ด๋ฌํ ์ฐธ์กฐ ํ์ ๋ค์ ๊ฐ๋น์ง ์ปฌ๋ ์ ์ ํน์ฑ๊ณผ ๊ฐ์ฒด์ ์๋ช ์ฃผ๊ธฐ๋ฅผ ๋ช ์์ ์ผ๋ก ๊ด๋ฆฌํ๊ธฐ ์ํด ์ฌ์ฉ๋๋ค.
1. ์ฐธ์กฐ ํ์ (Reference Types) ์ค๋ช
1.1 ๊ฐํ ์ฐธ์กฐ Strong Reference
๊ฐํ ์ฐธ์กฐ๋ ์๋ฐ์ ๊ธฐ๋ณธ ์ฐธ์กฐ ํ์ ์ผ๋ก, ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ณ ๋ณ์์ ํ ๋นํ๋ ์ผ๋ฐ์ ์ธ ๋ฐฉ๋ฒ์ด๋ค.
๊ธฐ๋ฅ
๊ฐํ ์ฐธ์กฐ๊ฐ ์กด์ฌํ๋ ํ, ๊ฐ๋น์ง ์ปฌ๋ ํฐ๋ ํด๋น ๊ฐ์ฒด๋ฅผ ์์งํ์ง ์๋๋ค. ์ฆ, ํ๋ก๊ทธ๋จ์ ์คํ ๊ฒฝ๋ก์์ ๊ฐ์ฒด์ ๋๋ฌํ ์ ์์ผ๋ฉด ํด๋น ๊ฐ์ฒด๋ ๋ฉ๋ชจ๋ฆฌ์์ ์ ๊ฑฐ๋์ง ์๋๋ค.
์์
Object obj = new Object(); // 'obj'๋ ๊ฐํ ์ฐธ์กฐ๋ฅผ ํตํด ์์ฑ๋ ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํฉ๋๋ค.
์ฌ์ฉ ์ํฉ
๋๋ถ๋ถ์ ๊ฒฝ์ฐ, ๊ฐ๋ฐ์๋ ๊ฐ์ฒด๋ฅผ ๊ฐํ ์ฐธ์กฐ๋ก ์ฌ์ฉํ๋ค. ๊ฐํ ์ฐธ์กฐ๋ ๊ฐ์ฒด๊ฐ ๋ ์ด์ ํ์ํ์ง ์์ ๋๊ฐ์ง ๊ฐ์ฒด๋ฅผ ๋ฉ๋ชจ๋ฆฌ์ ์ ์งํ๋ค.
1.2 ๋ถ๋๋ฌ์ด ์ฐธ์กฐ(Soft Reference)
๋ถ๋๋ฌ์ด ์ฐธ์กฐ๋ ๊ฐ์ฒด์ ๊ฐํ ์ฐธ์กฐ๊ฐ ์๊ณ , ๋ฉ๋ชจ๋ฆฌ๊ฐ ๋ถ์กฑํ ๋๋ง GC์ ์ํด ์์ง๋๋ ์ฐธ์กฐ ํ์ ์ด๋ค.
๊ธฐ๋ฅ
JVM์ ๋ฉ๋ชจ๋ฆฌ๊ฐ ๋ถ์กฑํ ๋๋ง ๋ถ๋๋ฌ์ด ์ฐธ์กฐ๊ฐ ์๋ ๊ฐ์ฒด๋ฅผ ์์งํ๋ค. ์ด ํ์ ์ ์ฐธ์กฐ๋ GC๊ฐ ๋ฉ๋ชจ๋ฆฌ ๋ถ์กฑ ์ํ์์๋ง ์์งํ๋ฏ๋ก, ๊ฐ์ฒด๋ฅผ ๊ฐ๋ฅํ ํ ์ค๋ ์ ์งํ๊ณ ์ถ์ ๋ ์ ์ฉํ๋ค.
์์
import java.lang.ref.SoftReference;
SoftReference<Object> softRef = new SoftReference<>(new Object());
// softRef๋ ๋ถ๋๋ฌ์ด ์ฐธ์กฐ์
๋๋ค. ๋ฉ๋ชจ๋ฆฌ๊ฐ ๋ถ์กฑํ ๋๋ง ์์ง๋ฉ๋๋ค.
์ฌ์ฉ ์ํฉ
์บ์์ ๊ฐ์ ๋ฉ์ปค๋์ฆ์์ ์ ์ฉํ๋ค. ์๋ฅผ ๋ค์ด, ์์ฃผ ์ฌ์ฉํ๋ ๊ฐ์ฒด๋ฅผ ์บ์์ ์ ์ฅํ๊ณ , ๋ฉ๋ชจ๋ฆฌ๊ฐ ๋ถ์กฑํด์ง ๋ GC๊ฐ ์บ์๋ฅผ ์ ๋ฆฌํ๋๋ก ํ๋ ค๋ ๊ฒฝ์ฐ์ ์ฌ์ฉ๋๋ค.
1.3 ์ฝํ ์ฐธ์กฐ Weak Reference
์ฝํ ์ฐธ์กฐ๋ ๊ฐ์ฒด์ ๋ํ ๊ฐํ ์ฐธ์กฐ๊ฐ ์์ผ๋ฉด, ์ฆ์ GC์ ์ํด ์์ง๋ ์ ์๋ ์ฐธ์กฐ ํ์ ์ด๋ค.
๊ธฐ๋ฅ
์ฝํ ์ฐธ์กฐ๋ก ์ฐธ์กฐ๋ ๊ฐ์ฒด๋ ๊ฐํ ์ฐธ์กฐ๊ฐ ์๋ ๊ฒฝ์ฐ GC์ ๋ค์ ์ฌ์ดํด์์ ์์ง๋๋ค. ๋ฐ๋ผ์ ๊ฐ์ฒด๊ฐ ๋ ์ด์ ํ์ํ์ง ์์๋ ๋ฉ๋ชจ๋ฆฌ ๋์๋ฅผ ๋ฐฉ์งํ ์ ์๋ค.
์์
import java.lang.ref.WeakReference;
WeakReference<Object> weakRef = new WeakReference<>(new Object());
// weakRef๋ ์ฝํ ์ฐธ์กฐ์
๋๋ค. ๊ฐํ ์ฐธ์กฐ๊ฐ ์์ผ๋ฉด ์ฆ์ ์์ง๋ ์ ์์ต๋๋ค.
์ฌ์ฉ ์ํฉ
WekaHashMap๊ณผ ๊ฐ์ ๋ฐ์ดํฐ ๊ตฌ์กฐ์์ ํค๊ฐ ์ฝํ ์ฐธ์กฐ๋ก ์ ์ง๋์ด, ํด๋น ํค์ ๋ํ ๊ฐํ ์ฐธ์กฐ๊ฐ ์์ผ๋ฉด ์๋์ผ๋ก ์ํธ๋ฆฌ๊ฐ ์ ๊ฑฐ๋๋ค. ์๋ฅผ ๋ค์ด, ์บ์๋ ๋ฆฌ์์ค ๊ด๋ฆฌ์์ ํค์ ์๋ช ์ด ์งง๊ฑฐ๋ ์์์ ์ด ๊ฒฝ์ฐ์ ์ฌ์ฉํ๋ค.
1.4 ์ ๋ น ์ฐธ์กฐ Phantom Reference
์ ๋ น ์ฐธ์กฐ๋ ๊ฐ์ฒด๊ฐ GC์ ์ํด ์์ง๋ ํ์๋ ์กด์ฌํ๋ ํน์ํ ์ฐธ์กฐ ํ์ ์ด๋ค. ๊ฐ์ฒด์ ๋ฉ๋ชจ๋ฆฌ๊ฐ ์ค์ ๋ก ํด์ ๋๊ธฐ ์ ์ ์ถ๊ฐ ์์ ์ ์ํํ๋ ๋ฐ ์ฌ์ฉ๋๋ค.
๊ธฐ๋ฅ
์ ๋ น ์ฐธ์กฐ๋ ๊ฐ์ฒด๊ฐ ๋ฉ๋ชจ๋ฆฌ์์ ์์ ํ ํด์ ๋๊ธฐ ์ ์ ์ํํด์ผ ํ๋ ์ ๋ฆฌ(clean-up) ์์ ์ ๊ฐ๋ฅํ๊ฒ ํ๋ค. ์ ๋ น ์ฐธ์กฐ๋ ReferenceQueue์ ํจ๊ป ์ฌ์ฉ๋๋ฉฐ, ๊ฐ์ฒด์ ๋ฉ๋ชจ๋ฆฌ ํด์ ๊ฐ ์๋ฐํ ์์ ์์ ์๋ฆผ์ ๋ฐ์ ์ญ ใ ฃใ ๋ค.
์์
import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;
Object obj = new Object();
ReferenceQueue<Object> refQueue = new ReferenceQueue<>();
PhantomReference<Object> phantomRef = new PhantomReference<>(obj, refQueue);
// phantomRef๋ ์ ๋ น ์ฐธ์กฐ์
๋๋ค. ๊ฐ์ฒด๊ฐ GC๋๊ธฐ ์ ์ ์๋ฆผ์ ๋ฐ์ ์ ์์ต๋๋ค.
obj = null; // ์ดํ GC๊ฐ obj๋ฅผ ์๊ฑฐํด๋ phantomRef๋ ์ฐธ์กฐ ํ์ ๋ค์ด๊ฐ๋ฉฐ ์ฒ๋ฆฌ๋ฉ๋๋ค.
์ฌ์ฉ ์ํฉ
๋ค์ดํธ๋ธ ๋ฆฌ์์ค ๊ด๋ฆฌ(์: ํ์ผ ํธ๋ค, ์์ผ ๋ฑ)์์ ์ฌ์ฉ๋๋ฉฐ, ๊ฐ์ฒด๊ฐ ์๊ฑฐ๋๊ธฐ ์ ์ ๋ฆฌ์์ค๋ฅผ ํด์ ํด์ผ ํ ๋ ์ ์ฉํ๋ค. ๋ํ, ๋ณต์กํ ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ์ ๊ด๋ จ๋ ๊ณ ๊ธ ์ฌ์ฉ ์ฌ๋ก์์๋ ์ ๋ น ์ฐธ์กฐ๋ฅผ ์ฌ์ฉํ์ฌ ์ ๋ฆฌ ์์ ์ ์ํํ ์ ์๋ค.
2. ๊ฐ๋ฐ์๊ฐ ๋ช ์์ ์ผ๋ก ์ฐธ์กฐ ํ์ ์ ์ฌ์ฉํ๋ ์ํฉ
2.1 ์บ์ ๊ตฌํ์์์ ์ฌ์ฉ
๋ถ๋๋ฌ์ด ์ฐธ์กฐ(Soft Reference)์ ์ฝํ ์ฐธ์กฐ(Weak Reference)๋ ์บ์ ๊ตฌํ์ ์ ์ฉํ๋ค. ์บ์๋ ์์ฃผ ์ฌ์ฉํ๋ ๋ฐ์ดํฐ๋ฅผ ๋ฉ๋ชจ๋ฆฌ์ ์ ์ฅํ ์ฑ๋ฅ์ ํฅ์์ํค๊ธฐ ์ํด ์ฌ์ฉ๋๋ค. ํ์ง๋ง,๋ฉ๋ชจ๋ฆฌ ๋์๋ฅผ ๋ฐฉ์งํ๊ธฐ์ํด ๋ฉ๋ชจ๋ฆฌ๊ฐ ๋ถ์กฑํ ๋ ์บ์๋ ๋ฐ์ดํฐ๋ฅผ ์๋์ผ๋ก ์ ๋ฆฌํ ์ ์์ด์ผ ํ๋ค.
import java.lang.ref.SoftReference;
import java.util.HashMap;
import java.util.Map;
public class CacheExample {
private Map<String, SoftReference<Object>> cache = new HashMap<>();
public void addToCache(String key, Object value) {
cache.put(key, new SoftReference<>(value));
}
public Object getFromCache(String key) {
SoftReference<Object> ref = cache.get(key);
if (ref != null) {
return ref.get(); // ๋ถ๋๋ฌ์ด ์ฐธ์กฐ๋ฅผ ํตํด ๊ฐ์ฒด๋ฅผ ๋ฐํ
}
return null;
}
}
์์ ์์ ์์, SoftReference๋ฅผ ์ฌ์ฉํ ์บ์๋ ๋ฐ์ดํฐ๊ฐ ๋ฉ๋ชจ๋ฆฌ ๋ถ์กฑ ์ ์๋์ผ๋ก GC์ ์ํด ์ ๋ฆฌ๋ ์ ์๋๋ก ํ๋ค.
2.2 ๋ฆฌ์์ค ๊ด๋ฆฌ์์์ ์ฌ์ฉ
์ ๋ น ์ฐธ์กฐ(Phantom Reference)๋ ๋ฆฌ์์ค ๊ด๋ฆฌ์์ ์ฌ์ฉ๋ ์ ์๋ค. ์๋ฅผ ๋ค์ด, ํ์ผ ํธ๋ค์ด๋ ๋คํธ์ํฌ ์์ผ๊ณผ ๊ฐ์ ๋ฆฌ์์ค๋ฅผ ์ฌ์ฉํ๋ ๊ฐ์ฒด๋ GC์ ์ํด ์์ง๋๊ธฐ ์ ์ ๋ฐ๋์ ๋ฆฌ์์ค๋ฅผ ํด์ ํด์ผ ํ๋ค.
import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;
public class ResourceCleaner {
private static class Resource {
// ๋ฆฌ์์ค๋ฅผ ์ฌ์ฉํ๋ ๊ฐ์ฒด
}
private static class CleanupTask extends PhantomReference<Resource> {
public CleanupTask(Resource referent, ReferenceQueue<? super Resource> q) {
super(referent, q);
}
public void cleanup() {
System.out.println("Cleaning up resources...");
// ๋ฆฌ์์ค ํด์ ์์
์ํ
}
}
public static void main(String[] args) {
ReferenceQueue<Resource> refQueue = new ReferenceQueue<>();
Resource resource = new Resource();
CleanupTask cleanupTask = new CleanupTask(resource, refQueue);
resource = null; // ๊ฐํ ์ฐธ์กฐ ํด์
System.gc(); // GC ๊ฐ์ ์คํ
// ์ฐธ์กฐ ํ์์ ์ ๋ น ์ฐธ์กฐ๋ฅผ ํ์ธํ๊ณ , ์ ๋ฆฌ ์์
์ํ
CleanupTask polledTask = (CleanupTask) refQueue.poll();
if (polledTask != null) {
polledTask.cleanup();
}
}
}
์์ ์์ ์์ PhantomReference๋ ReferenceQueue์ ํจ๊ป ์ฌ์ฉ๋์ด, ๊ฐ์ฒด๊ฐ GC์ ์ํด ์์ง๋๊ธฐ ์ง์ ์ ์ ๋ฆฌ ์์ ์ ์ํํ ์ ์๋๋ก ํ๋ค.
3. ๊ฒฐ๋ก
์๋ฐ์ ๋ค์ํ ์ฐธ์กฐ ํ์ ์ ๊ฐ๋ฐ์๊ฐ ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ ๋ฐ ๊ฐ๋น์ง ์ปฌ๋ ์ ์ ์ธ๋ฐํ๊ฒ ์ ์ดํ ์ ์๋๋ก ๋๋๋ค. ๊ฐ ์ฐธ์กฐ ํ์ ์ ๊ฐ์ฒด์ ์๋ช ๊ด๋ฆฌ์ ์์ด ๊ณ ์ ํ ์ฉ๋์ ์ด์ ์ ์ ๊ณตํ๋ฉฐ, ๊ฐ๋ฐ์๋ ํ๋ก๊ทธ๋จ์ ์๊ตฌ ์ฌํญ์ ๋ง๊ฒ ์ ์ ํ ์ฐธ์กฐ ํ์ ์ ์ ํํด ๋ฉ๋ชจ๋ฆฌ ํจ์จ์ฑ๊ณผ ์์ ์ฑ์ ๊ทน๋ํํ ์ ์๋ค. SoftReference, WeakReference, ๊ทธ๋ฆฌ๊ณ PhantomReference๋ ๋ฉ๋ชจ๋ฆฌ ๋์ ๋ฐฉ์ง ์บ์ ๊ด๋ฆฌ, ๋ฆฌ์์ค ์ ๋ฆฌ ๋ฑ ๋ค์ํ ์๋๋ฆฌ์ค์์ ํ์ฉ๋ ์ ์๋ค.
'๋น ๊ตฌ๋ฉ ์ฑ์ฐ๊ธฐ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Java] Iterator. for ๋ฌธ๊ณผ์ ๋น๊ต (0) | 2024.08.29 |
---|---|
[ํ๋ก๊ทธ๋๋ฐ ๊ฐ๋ ][Java] ๋๊ธํ ํ๊ฐ Lazy Evaluation (0) | 2024.08.29 |
[Java] ์ฐธ์กฐ ๋๋ฌ ๊ฐ๋ฅ์ฑ reachability (3) | 2024.08.28 |
[JVM] Out of Memory VS Memory Leak (0) | 2024.08.28 |
[Kotlin][ํ๋ก๊ทธ๋๋ฐ ๊ฐ๋ ] Tail Recursion Optimization (Tail Call Optimization) (2) | 2024.08.28 |