---《java編程思想》 讀書筆記
--- 2017/3/15java
讀《java編程思想》讀到初始化與清理一章,文中說起java的finalize()方法,聯想到了C++的析構函數。finalize()方法與析構函數存在自然差異,這種差異源於語言自己機制的不一樣。c++
在C++中,對象是能夠在棧上分配的,也能夠在堆上分配。在棧上分配的對象,也就是函數的局部變量,當超出塊的"}"時,生命期便結束了。在堆上分配的對象,使用delete的時候,對象的生命期也就結束了。所以在C++中,對象的內存在哪一個時刻被回收,是能夠肯定的(假設程序沒有缺陷)。java秉承一切皆爲對象的思想,對象僅能經過new來建立,所以java的對象是在堆上分配的內存。這些堆上的對象,若是沒有做用了(無引用指向它),將等待垃圾回收器來回收其佔用的內存。而垃圾回收期什麼時候運行,沒法提早預知,甚至有的時候直到程序退出都沒有進行垃圾回收,程序所佔內存直接由操做系統來回收。因此在java中,對象的內存在哪一個時刻回收,取決於垃圾回收器什麼時候運行。所以,C++與java中,對無用對象的回收時間是不一樣的。程序員
一旦C++的對象要被回收了,在回收該對象以前對象的析構函數將被調用,而後釋放對象佔用的內存;而java中編程
一旦垃圾回收器準備好釋放對象佔用的存儲空間,將首先調用其finalize()方法, 而且在下一次垃圾回收動做發生時,纔會真正的回收對象佔用的內存(《java 編程思想》)函數
可見在java中,調用GC不等於真正地回收內存資源,並且在垃圾回收中對象存在狀態的變化。操作系統
C++的析構函數用來作一些必要的工做,例如釋放掉指針成員所指向的對象所佔的內存,由於C++沒有java的垃圾回收器,全部new出來的對象,都要顯式地delete掉,避免內存泄漏。《Effective C++》中說起,基類須要將析構函數聲明爲virtual函數,這是爲了能夠經過子類對象指針正確地釋放掉基類的資源。總的來講,在C++中,析構函數和資源的釋放息息相關,能不能正確處理析構函數,關乎可否正確回收對象內存資源。 在java中,全部的對象,包括對象中包含的其餘對象,它們所佔的內存的回收都依靠垃圾回收器,所以不須要一個函數如C++析構函數那樣來作必要的垃圾回收工做。固然存在本地方法時須要finalize()方法來清理本地對象。在《java編程思想》中說起,finalize()方法的一個做用是用來回收「本地方法」中的本地對象——C/C++代碼所分配的內存,因爲這部分的內存只能由delete/free來釋放,所以能夠放在finalize()方法中來作。在實際生產環境中,我較少(或說基本沒有)看到java類實現了finalize()方法。能夠說java最大程度地弱化了內存管理對應用程序員的束縛,而c++則對此要求嚴格多了。.net
另外,看到了兩篇介紹java對象回收流程的文章:http://www.javashuo.com/article/p-vodmhnbo-w.html http://blog.csdn.net/rsljdkt/article/details/12242007
這些內容應該是在JVM的書籍中有涉及,這又是值得研究的一個點了。指針