面試題:Java中的垃圾收集器相對于以前的語言優勢是什么?
答案:過去的語言(如C語言)要求程序員顯示的分配內存、釋放內存。程序在需要時分配內存,不需要時釋放內存。但是這種做法常常引起“內存泄露”,即由于某種原因使分配的內存始終沒有得到釋放。如果該任務不斷重復,程序早晚會耗盡內存并異常終止,至少無法繼續運行。相比之下,Java不要求程序員顯示的分配地分配內存和釋放內存,避免了很多潛在問題。Java在創建對象時會自動分配內存,并當該對象的引用不存在時釋放這塊內存.
Java中使用被稱為垃圾收集器的技術來監視Java程序的運行,當對象不再使用時,就自動釋放對象所使用的內存。Java使用一系列軟指針來跟蹤對象的各個引用,并用一個對象表格將這些軟指針映射為對象的引用。之所以稱為軟指針,Java的垃圾收集器能夠以單獨的線程在后臺運行,并依次檢查每個對象。統統更改對象表項,垃圾收集器可以標記對象、移除對象、移動對象或檢查對象。
垃圾收集器是自動運行的,一般情況下,無需顯示的請求垃圾收集器。程序運行時,垃圾收集器會不時檢查對象的哥哥引用,并且回收無引用對象所占用的內存。調用system類中的靜態go()方法可以運行垃圾收集器,但這樣并不能保證立即回收指定對象。
拓展知識:變量的內存分配情況
我們在使用垃圾回收時需要注意以下幾點,或許可以作為寫程序時的準則。
(1)不要試圖去假定垃圾收集發生的時間,這一切都是位置的。比如,方法中的一個臨時對象在方法調用完畢后就變成了無用對象,這個時候它的內存就可以被釋放。
(2)Java中提供了一些和垃圾收集器打交道的類,而且提供了一種強行執行垃圾收集的方法——調用了system.gc(),但這同樣是一個不確定的方法,Java中并不保證每次調用該方法就一定能夠啟動垃圾收集器,它只不過會向JVM發出這樣一個申請,到底是否真正只想垃圾收集,一切都是個未知數。
(3)挑選適合自己的垃圾收集器。一般來說,如果系統沒有特殊和苛刻的性能要求,可以采用JVM的默認選項。否則可以考慮使用有針對性的垃圾收集器,比如增量收集器就比較適用于實時性要求較高的系統中,若系統具有較高的配置,有比較多的閑置資源,則可以考慮使用并行標記/清除收集器。
(4)關鍵的也是難把握的問題是內存泄露。良好的編程習慣和嚴謹的編程態度永遠是最重要的,不要讓自己的一個小錯誤導致內存出現大漏洞。
(5)盡早釋放無用對象的引用。大多數程序員在使用臨時變量的時候,都是讓引用變量在退出活動域后,自動設置為null,按時垃圾收集器來收集該對象,還必須注意該引用的對象是否被監聽,如果是,則要去掉監聽器,然后在賦空值。也就是說,對于頻繁申請內存和釋放內存的操作,還是自己控制一下比較好,但是system.gc()的方法不一定使用,最好使用finalize強制執行或者寫自己的finalize方法。
更多Java知識,Java視頻,Java教程盡在動力節點Java培訓,關注動力節點官方微信,獲得一手Java面試題。