item 8 junghyunlyoo - JAVA-JIKIMI/EFFECTIVE-JAVA3 GitHub Wiki
@Override
public void finalize() {
// ...
}
Object ํด๋์ค์ ์ ์๋ finalize ๋ฉ์๋๋ฅผ Overrideํ๋ฉด ํด๋น ๊ฐ์ฒด๊ฐ GC ๋์์ด ๋ ๋ finalize ๋ฉ์๋๊ฐ ํธ์ถ๋๋ค.
public class CleaningExample implements AutoCloseable {
// A cleaner, preferably one shared within a library
private static final Cleaner cleaner = <cleaner>;
static class State implements Runnable {
State(...) {
// initialize State needed for cleaning action
}
public void run() {
// cleanup action accessing State, executed at most once
}
}
private final State;
private final Cleaner.Cleanable cleanable
public CleaningExample() {
this.state = new State(...);
this.cleanable = cleaner.register(this, state);
}
public void close() {
cleanable.clean();
}
}
cleaner์ ์ฌ์ฉ ๋ฐฉ๋ฒ์ finalizer๋ณด๋ค ์ฝ๊ฐ ๋ณต์กํ๋ค.
๊ทธ๋ฆฌ๊ณ finalizer์ ๋ฌ๋ฆฌ cleaner๋ ํด๋์ค์ public API์ ๋ํ๋์ง ์๋๋ค.
์ฐ์ CleaningExample ์ธ์คํด์ค๊ฐ close ๋ฉ์๋๋ฅผ ํธ์ถํ๊ฒ ๋๋ฉด cleaner๊ฐ ์คํ๋๋ค.
๊ทธ๋ฆฌ๊ณ cleaner๋ State ์ค๋ ๋๋ฅผ ์คํ์ํค๊ฒ ๋๊ณ State ์ค๋ ๋ ๋ด๋ถ์ ์์ ํด์ ์ ๊ด๋ จ๋ ๋ด์ฉ์ ์ฑ์ฐ๋ฉด ๋๋ค.
์ฐธ๊ณ ๋ก State ์ค๋ ๋๋ ๋ฑ ํ๋ฒ๋ง ํธ์ถ๋๋ค. ๋ง์ฝ ์ฌ์ฉ์๊ฐ CleaningExample ์ธ์คํด์ค์ close๋ฅผ ํธ์ถํ์ง ์๋๋ค๋ฉด
GC๊ฐ CleaningExample ์ธ์คํด์ค๋ฅผ ํ์ํ ๋ cleanable.clean์ ์คํ์์ผ์ค ๊ฒ์ด๋ค.
๊ทธ๋ฐ๋ฐ GC์ ๋ฐ๋ผ ์ค์ ๋ก ์คํ๋ ์๋ ์คํ์ด ์ ๋ ์๋ ์๋ค๋ ๊ฒ์ ์ฃผ์ํด์ผ ํ๋ค.
finalize ๋ฉ์๋๋ฅผ ์ฌ์ ์ํ๋ ๊ฒ์ ์ง์ํด์ผํ ์ด์ ๊ฐ ๋ช ๊ฐ์ง ์๋ค.
-
์ธ์ ํธ์ถ๋ ์ง ์์ธกํ ์ ์๋ค.
-
๋ง์ ํธ์ถ๋์ ๋, ์ํฉ์ ๋ฐ๋ผ ์ํํ ์ ์๋ค.
๊ทธ๋์ ๊ธฐ๋ณธ์ ์ผ๋ก '์ฐ์ง ๋ง์์ผ' ํ๋ค.
Java 9์์๋ finalize ๋ฉ์๋๋ฅผ ์ฌ์ฉ ์์ (deprecated) API๋ก ์ง์ ํ๊ณ
์๋์ ์ผ๋ก ๋ ์ํํ clean ๋ฉ์๋๋ฅผ ๊ทธ ๋์์ผ๋ก ์๊ฐํ๊ธฐ๋ ํ๋ค.
ํ์ง๋ง clean ๋ฉ์๋๋ ์ญ์ ์์ธก ๋ถ๊ฐ๋ฅํ๊ณ ์ผ๋ฐ์ ์ผ๋ก ๋ถํ์ํ๋ค.
finalize ๋ฉ์๋๋ ์ธ์ ์คํ๋ ์ง ์ ์ ์๋ค.
finalize ๋ฉ์๋๋ GC๊ฐ ์คํ๋ ๋ ๋ฐ๋ก ์คํ๋์ง ์๋๋ค.
๊ทธ ์ด์ ๋ ์ด๋ ๋ค.
GC๊ฐ ์คํ๋ ๋ ๊ฐ์ฒด๋ค์ ์ค์บํ๋๋ฐ, ๊ทธ ๊ฐ์ฒด๊ฐ finalize ๋ฉ์๋๋ฅผ ์ฌ์ ์ํ์ ๊ฒฝ์ฐ ๊ทธ ๊ฐ์ฒด๋ Finalization Queue์ ๋ค์ด๊ฐ๊ฒ ๋๋ค.
๊ทธ๋ฆฌ๊ณ Finalizer์ ์ํด ์ ๋ฆฌ๊ฐ ๋๋ค.
Fianlizer๊ฐ Queue์ ๋ค์ด๊ฐ ๊ฐ์ฒด๋ค์ ๋น ๋ฅด๊ฒ ์ฒ๋ฆฌํ๋ฉด ์ข์ํ ๋ฐ ์์ฝ๊ฒ๋ Fianlizer ์ค๋ ๋๋ ์ฐ์ ์์๊ฐ ํญ์ ๊ฐ์ฅ ๋์ง๋ ์๋ค.
Finalizer ์ค๋ ๋๋ฅผ ์ง์ ์ปจํธ๋กคํ ์ ์์ด์ ์ฐ์ ์์๋ฅผ ์ง์ ํ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค.
๊ทธ๋์ Finalizer ์ค๋ ๋๊ฐ ๋ค๋ฅธ ์ค๋ ๋๋ค์ ์ฐ์ ์์๊ฐ ๋ฐ๋ ค ์คํ์ด ๋ฏธ๋ค์ง๋ค๋ฉด Finalization Queue์ ๊ฐ์ฒด๊ฐ ์์ด๊ฒ ๋๋ค.
๊ทธ๋ ๊ฒ ๋๋ฉด OutOfMemory ์ค๋ฅ๊ฐ ๋ฐ์ํ ์๋ ์๋ค.
ํน์ finalize ๋ฉ์๋ ๋ด์ file์ ๊ด๋ จ๋ ๊ฐ์ฒด์ ์์์ ํ์ํ๋ ๋ก์ง์ด ๋ค์ด์๋ค๋ฉด,
์๋ก์ด ํ์ผ์ ์ด์ง ๋ชปํด ํ๋ก๊ทธ๋จ์ด ์คํจํด๋ฒ๋ฆด ์๋ ์๋ค.
์๋ํ๋ฉด ์์คํ ์ด ๋์์ ์ด ์ ์๋ ํ์ผ ๊ฐ์๋ ํ๊ณ๊ฐ ์๊ธฐ ๋๋ฌธ์ด๋ค.
finalizer๋ cleaner๋ฅผ ์ผ๋ง๋ ์ ์ํ ์ํํ ์ง๋ ์ ์ ์ผ๋ก
GC ์๊ณ ๋ฆฌ์ฆ์ ๋ฌ๋ ธ์ผ๋ฉฐ ์ด๋ GC ๊ตฌํ๋ง๋ค ์ฒ์ฐจ๋ง๋ณ์ด๋ค.
finalizer๋ cleaner ์ํ ์์ ์ ์์กดํ๋ ํ๋ก๊ทธ๋จ์ ๋์ ๋ํ ๋ง์ฐฌ๊ฐ์ง๋ค.
๋ด JVM์์๋ ์ ๋์๊ฐ๋๋ฐ, ๋ค๋ฅธ JVM์์๋ ์คํจํ ์๋ ์๋ค.
ํํธ cleaner๋ ์์ ์ ์ํํ ์ค๋ ๋๋ฅผ ์ ์ดํ ์ ์๋ค๋ ๋ฉด์์ ์กฐ๊ธ ๋ซ๋ค.
ํ์ง๋ง ์ฌ์ ํ ๋ฐฑ๊ทธ๋ผ์ด๋์์ ์ํ๋๋ฉฐ GC์ ํต์ ํ์ ์์ผ๋ ์ฆ๊ฐ ์ํ๋๋ฆฌ๋ผ๋ ๋ณด์ฅ์ ์๋ค.
์๋ฐ ์ธ์ด ๋ช ์ธ๋ finalizer๋ cleaner์ ์ํ ์์ ๋ฟ ์๋๋ผ ์ํ ์ฌ๋ถ์กฐ์ฐจ ๋ณด์ฅํ์ง ์๋๋ค.
์ ๊ทผํ ์ ์๋ ์ผ๋ถ ๊ฐ์ฒด์ ๋ธ๋ฆฐ ์ข ๋ฃ ์์ ์ ์ ํ ์ํํ์ง ๋ชปํ ์ฑ ํ๋ก๊ทธ๋จ์ด ์ค๋จ๋ ์๋ ์๋ค๋ ์๊ธฐ๋ค.
๋ฐ๋ผ์ ํ๋ก๊ทธ๋จ ์์ ์ฃผ๊ธฐ์ ์๊ด์๋, ์ํ๋ฅผ ์๊ตฌ์ ์ผ๋ก ์์ ํ๋ ์์ ์์๋ ์ ๋ finalizer๋ cleaner์ ์์กดํด์๋ ์๋๋ค.
์๋ฅผ ๋ค์ด DB๊ฐ์ ๊ณต์ ์์์ ์๊ตฌ ๋ฝ(lock) ํด์ ๋ฅผ finalizer๋ cleaner์ ๋งก๊ฒจ ๋์ผ๋ฉด ๋ถ์ฐ ์์คํ ์ ์ฒด๊ฐ ์์ํ ๋ฉ์ถ ๊ฒ์ด๋ค.
ํน์ฌ๋ System.gc๋ System.runFinalization ๋ฉ์๋์ ํํน๋์ง ๋ง์.
finalizer์ cleaner๊ฐ ์คํ๋ ๊ฐ๋ฅ์ฑ์ ๋์ฌ์ค ์๋ ์์ผ๋, ๋ณด์ฅํด์ฃผ์ง ์๋๋ค.
์ฌ์ค ์ด๋ฅผ ๋ณด์ฅํด์ฃผ๊ฒ ๋ค๋ ๋ฉ์๋๊ฐ 2๊ฐ ์์๋ค.
๋ฐ๋ก System.runFinalizersOnExit์ ๊ทธ ์๋ฅ์ด์ธ Runtime.runFianlizersOnExit์ด๋ค.
ํ์ง๋ง ์ด ๋ ๋ฉ์๋๋ ์ฌ๊ฐํ ๊ฒฐํจ ๋๋ฌธ์ ์์ญ๋ ๊ฐ ์งํ๋ฐ์ ์๋ค.
(์ฑ ์์ ๋ฐฉ๊ธ ์ ๋ฌธ์ฅ ์์ [ThreadStop] ์ด๋ผ๊ณ ์ ํ์๋๋ฐ, ์๋ง ๋ ์๋ฅ์ด ๋ฉ์๋๊ฐ ์คํ๋๋ฉด GC์ Stop The World์ ๋น์ทํ ์ํฉ์ด ๋ฒ์ด์ง๋๋ณด๋ค.)
finalize ๋ฉ์๋ ์คํ ์ค ๋ฐ์ํ๋ ์์ธ๋ ๋ฌด์๋๋ฉฐ, ์ฒ๋ฆฌํ ์์ ์ด ๋จ์๋๋ผ๋ ๊ทธ ์๊ฐ ์ข ๋ฃ๋๋ค.
์ก์ง ๋ชปํ ์์ธ ๋๋ฌธ์ ํด๋น ๊ฐ์ฒด๋ ์์นซ ๋ง๋ฌด๋ฆฌ๊ฐ ๋ ๋ ์ํ๋ก ๋จ์ ์ ์๋ค.
๊ทธ๋ฆฌ๊ณ ๋ค๋ฅธ ์ค๋ ๋๊ฐ ์ด์ฒ๋ผ ํผ์๋ ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ๋ ค ํ๋ค๋ฉด ์ด๋ป๊ฒ ๋์ํ ์ง ์์ธกํ ์ ์๋ค.
๋ณดํต์ ๊ฒฝ์ฐ์ ์ก์ง ๋ชปํ ์์ธ๊ฐ ์ค๋ ๋๋ฅผ ์ค๋จ์ํค๊ณ ์คํ ์ถ์ ๋ด์ญ์ ์ถ๋ ฅํ๊ฒ ์ง๋ง,
๊ฐ์ ์ผ์ด finalizer์์ ์ผ์ด๋๋ค๋ฉด ๊ฒฝ๊ณ ์กฐ์ฐจ ์ถ๋ ฅํ์ง ์๋๋ค.
(๊ทธ๋๋ง cleaner๋ฅผ ์ฌ์ฉํ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ์์ ์ ์ค๋ ๋๋ฅผ ํต์ ํ๊ธฐ ๋๋ฌธ์ ์ด๋ฌํ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ง ์๋๋ค.)
์์์ ํด์ ํ๋ ๋ฐฉ๋ฒ์๋ finalizer์ cleaner ๋ง๊ณ ๋ AutoCloseable ์ธํฐํ์ด์ค์ close ๋ฉ์๋๋ฅผ ํ์ฉํ๋ ๋ฐฉ๋ฒ๋ ์๋ค. (item 9)
๊ฒฐ๋ก ์ ์ผ๋ก ์์ ํด์ ์๋ ์์๋ ์๋์ ๊ฐ๋ค.
AutoCloseable > finalizer = cleaner
์๋ํ๋ฉด finalizer์ cleaner๋ GC์ ํจ์จ์ ๋จ์ด๋จ๋ฆฌ๊ธฐ ๋๋ฌธ์ด๋ค.
finalizer๊ฐ ๊ณต๊ฒฉ๋นํ๋ ์๋ฆฌ๋ ์ด๋ ๋ค.
A ํด๋์ค์ ์ด๋ฅผ ์์ํ B ํด๋์ค๊ฐ ์๋ค.
A ํด๋์ค์ finalize ๋ฉ์๋๋ฅผ ์ฌ์ ์ํด๋์ง ์์์ ์์ ํ๋ค.
๊ทธ๋ฐ๋ฐ B ํด๋์ค๋ finalize ๋ฉ์๋๋ฅผ ์ฌ์ ์ํด ๋์๋ค.
๊ทธ๋ฆฌ๊ณ B ํด๋์ค์ ์์ฑ์๊ฐ ์คํ๋ ๋ ์์ธ๊ฐ ๋ฐ์ํ์ฌ finalize ๋ฉ์๋๊ฐ ์คํ๋๋ค.
B ํด๋์ค๊ฐ ์ฌ์ ์ํ finalize ๋ฉ์๋์์๋ B ํด๋์ค์ static ํ๋๋ ๋ฌผ๋ก ์ด๊ณ
A ํด๋์ค์ static ํ๋์๊น์ง ์ ๊ทผํ ์๋ ์๋ค.
๊ทธ๋ฆฌ๊ณค ์ด ํ๋์ ์์ ์ ์ฐธ์กฐ๋ฅผ ํ ๋นํด๋ฒ๋ฆฐ๋ค๋ฉด GC๊ฐ ํด๋น ๊ฐ์ฒด๋ฅผ ์์งํ์ง ๋ชปํ๋ค.
์ด๋ ๊ฒ ์ผ๊ทธ๋ฌ์ง ๊ฐ์ฒด๊ฐ ๋ง๋ค์ด์ง๊ณ ๋๋ฉด, ์ด ๊ฐ์ฒด์ ๋ฉ์๋๋ฅผ ํธ์ถํด
์ ์ด์๋ ํ์ฉ๋์ง ์์์ ์์ ์ ์ํํด๋ฒ๋ฆด ์๋ ์๋ค.
๊ฐ์ฒด ์์ฑ์ ๋ง์ผ๋ ค๋ฉด ์์ฑ์์์ ์์ธ๋ฅผ ๋์ง๋ ๊ฒ๋ง์ผ๋ก ์ถฉ๋ถํ์ง๋ง finalizer๊ฐ ์๋ค๋ฉด ๊ทธ๋ ์ง๋ ์๋ค.
์ด ๊ณต๊ฒฉ์ ๋ํ ๋์์ด 2๊ฐ์ง๊ฐ ์๋ค.
-
class๋ฅผ final๋ก ๋ง๋ค๊ธฐ (์ ์์์๋ A ํด๋์ค)
-
์๋ฌด ์ผ๋ ํ์ง ์๋ final finalize ๋ฉ์๋ ๋ง๋ค๊ธฐ
ํ์ผ์ด๋ ์ค๋ ๋ ๋ฑ ์ข ๋ฃํด์ผ ํ ์์์ ๋ด๊ณ ์๋ ๊ฐ์ฒด์ ํด๋์ค์์ finalizer๋ cleaner๋ฅผ ๋์ ํด์ค ๋ฌ์์ ๋ฌด์์ผ๊น?
๋ฐ๋ก AutoCloseable์ ๊ตฌํํ๋ ๊ฒ์ด๋ค.
๊ทธ๋ฆฌ๊ณ close ๋ฉ์๋๋ฅผ ํธ์ถํ๊ฑฐ๋ ์๋์ผ๋ก ํธ์ถ๋๋ try-with-resource ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด๋ค. (item 9) ์์์ ์ ๊น ์ธ๊ธํ๊ธฐ๋ ํ๋ค.
AutoCloseable ์ฌ์ฉ ๊ฟํ์ด ์๋ค. ๊ฐ ์ธ์คํด์ค๋ ์์ ์ด ๋ซํ๋์ง๋ฅผ ์ถ์ ํ๋ ๊ฒ์ด ์ข๋ค.
์๋๋ FileInputStream์ close ๋ฉ์๋์ด๋ค.
public void close() throws IOException {
synchronized (closeLock) {
if (closed) {
return;
}
closed = true;
}
if (channel != null) {
channel.close();
}
fd.closeAll(new Closeable() {
public void close() throws IOException {
close0();
}
});
}
์์ธํ ๋ณด๋ฉด closed๋ผ๋ bool ๋ณ์๊ฐ ์๋ค.
์ด ๋ณ์๋ฅผ ํตํด close ๋ฉ์๋์์ ์ด ๊ฐ์ฒด๋ ๋ ์ด์ ์ ํจํ์ง ์์์ ๊ธฐ๋กํ๋ ๊ฒ์ด๋ค.
๊ทธ๋์ ํด๋์ค ๋ด์ ๋ค๋ฅธ ๋ฉ์๋๋ ์ด ํ๋๋ฅผ ๊ฒ์ฌํด์ ๊ฐ์ฒด๊ฐ ๋ซํ ํ์ ๋ถ๋ ธ๋ค๋ฉด
IllegalStateException์ ๋์ง๋ฉด ์์ธกํ์ง ๋ชปํ๋ ์์ธ๋ฅผ ํ๋๋ผ๋ ์ค์ผ ์ ์๋ค.
๊ทธ๋ ๋ค๋ฉด ์ด๊ฒ๋ค์ ๋๋์ฒด ์ด๋์ ์ฐ๋ฉด ์ข์๊ฒ์ผ๊น. ์ ์ ํ ์ฐ์์๊ฐ ๋ ๊ฐ์ง ์๋ค.
[์์์ ์์ ์๊ฐ close ๋ฉ์๋๋ฅผ ๋ฏธ์ฒ ํธ์ถํ์ง ์๋ ๊ฒ์ ๋๋นํ ์์ ๋ง]
finalizer๋ cleaner๊ฐ ์ฆ์(ํน์ ๋๊น์ง) ํธ์ถ๋๋ฆฌ๋ผ๋ ๋ณด์ฅ์ ์๋ค.
ํ์ง๋ง ๋ฐ๋์ close ๋ฉ์๋๊ฐ ํธ์ถ๋์ด์ผ ํ๋ ์ํฉ์์๋
finalizer๋ cleaner์ close ๋ฉ์๋ ํธ์ถ์ ๋ฃ์ด์ ๊ทธ๋๋ง ์์ ์ฅ์น๋ฅผ ํ๋ ๋ ๋๋ ๊ฒ์ด ๋์ ๊ฒ์ด๋ค.
FileInputStream, FileOutputStream, ThreadPoolExcecutor๊ฐ ๊ทธ ์์ด๋ค.
๊ทธ๋ฆฌ๊ณ ๋งจ ์์ cleaner ์์ ์์๋ ์์ ๋ง์ ํ์ธํ ์ ์๋ค.
(๋ค์ ๊ฐ์กฐํ์ง๋ง ์์ ๋ง์ ์ค์นํ์ด๋ ์ด ์์ ๋ง ์กฐ์ฐจ ์คํ์ด ์๋ ์๋ ์๋ค!)
[๋ค์ดํฐ๋ธ ํผ์ด์ ์ฐ๊ฒฐ๋ ๊ฐ์ฒด์ ์ฌ์ฉ]
๋ค์ดํฐ๋ธ ํผ์ด(native peer)๋ ์ผ๋ฐ ์๋ฐ ๊ฐ์ฒด๊ฐ ๋ค์ดํฐ๋ธ ๋ฉ์๋๋ฅผ ํตํด ๊ธฐ๋ฅ์ ์์ํ ๋ค์ดํฐ๋ธ ๊ฐ์ฒด๋ฅผ ๋งํ๋ค.
๋ค์ดํฐ๋ธ ํผ์ด๋ ์๋ฐ ๊ฐ์ฒด๊ฐ ์๋๋ GC๋ ๊ทธ ์กด์ฌ๋ฅผ ๋ชจ๋ฅธ๋ค.
๊ทธ ๊ฒฐ๊ณผ ์๋ฐ ํผ์ด๋ฅผ ํ์ํ ๋ ๋ค์ดํฐ๋ธ ๊ฐ์ฒด๊น์ง๋ ํ์ํ ์ ์๋ค.
finalizer๋ cleaner๊ฐ ๋ฑ์ฅํ๋ฉด ์ข์ ์ํฉ์ด๋ค.
๋จ, ์ฑ๋ฅ ์ ํ๋ฅผ ๊ฐ๋นํ ์ ์๊ณ ๋ค์ดํฐ๋ธ ํผ์ด๊ฐ ์ฌ๊ฐํ ์์์ ๊ฐ์ง๊ณ ์์ง ์์ ๋์๋ง ํด๋น๋๋ค.
์ฑ๋ฅ ์ ํ๋ฅผ ๊ฐ๋นํ ์ ์๊ฑฐ๋ ๋ค์ดํฐ๋ธ ํผ์ด๊ฐ ์ฌ์ฉํ๋ ์์์ ์ฆ์ ํ์ํด์ผ ํ๋ค๋ฉด, ์์ ์ค๋ช
ํ close ๋ฉ์๋๋ฅผ ์ฌ์ฉํ์.
cleaner(java 8๊น์ง๋ finalizer)๋ ์์ ๋ง ์ญํ ์ด๋ ์ค์ํ์ง ์์ ๋ค์ดํฐ๋ธ ์์ ํ์์ฉ์ผ๋ก๋ง ์ฌ์ฉํ์
๋ฌผ๋ก ์ด๋ฐ ๊ฒฝ์ฐ๋ผ๋ ๋ถํ์ค์ฑ๊ณผ ์ฑ๋ฅ ์ ํ์ ์ฃผ์ํด์ผ ํ๋ค.