Java 9 廢棄了 finalize 方法,FileInputStream 等也清空了 finalize 方法的實作,改用 PhantomReference 的機制,JVM 有個執行緒會監控 Reference,在實例不再被參考時,呼叫 close 方法。
至於相容性的部份,若有 FileInputStream 的子類,且自定義了 close 方法,實例化時會有個 AltFinalizer 產生,AltFinalizer 建立時會包裹 FileInputStream,AltFinalizer 的作用就是等著被回收時,呼叫自定義的 finalize 方法(被加了 @SuppressWarnings("deprecation")),其中呼叫了 FileInputStream 的 close 方法。
繞來繞去的 ...
Every time you create either a FileInputStream or a FileOutputStream you are creating an object, even if you close it correctly and promptly, it will be put into a special category that only gets cleaned up when the garbage collector does a full GC.
就算自己 close 了也不是真的 close 了?還是得依賴 Full GC 呼叫 finalize 才會真的 close?有所謂的 a special category?
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();
}
});
}
protected void finalize() throws IOException {
if ((fd != null) && (fd != FileDescriptor.in)) {
/* if fd is shared, the references in FileDescriptor
* will ensure that finalizer is only called when
* safe to do so. All references using the fd have
* become unreachable. We can call close()
*/
close();
}
}
如果他的意思是因為 override 了 finalize,所以會被排入 GC 時得呼叫 finalize,那也很奇怪, finalize 一直都在那啊?還是說他的意思是,finalize 裡寫的程式碼檢查會造成不必要的開銷?
去看看別的地方的 comments,也有人覺得這說法不太對。
應該是你說的第二點,非 trivial finalize() 的 instance 會被丟到 finalize queue。 關於trivial finalize()1