● 請簡單描述一下垃圾回收器的基本原理是什么?還有垃圾回收器可以馬上回收內存嗎?並且有什么辦法可以主動通知虛擬機進行垃圾回收呢?
考察點:垃圾回收
參考回答:
對於GC來說,當程序員創建對象時,GC就開始監控這個對象的地址、大小以及使用情況。通常,GC采用有向圖的方式記錄和管理堆(heap)中的所有對象。通過這種方式確定哪些對象是”可達的”,哪些對象是”不可達的”。當GC確定一些對象為”不可達”時,GC就有責任回收這些內存空間。可以。程序員可以手動執行System.gc(),通知GC運行,但是Java語言規范並不保證GC一定會執行。
● 請問,在java中會存在內存泄漏嗎?請簡單描述一下。
考察點:內存
參考回答:
Java中的確存在Java的內存泄漏, 並且事態可以變得相當嚴重
Java garbage collector自動釋放哪些內存里面程序不在需要的對象, 以此避免大多數的其他程序上下文的內存泄漏. 但是Java應用程序依舊會有相當的內存泄漏. 查找原因會十分困難.
有兩類主要的Java內存泄漏:
* 不再需要的對象引用
* 未釋放的系統資源
2.2 非必要的對象引用
Java代碼常常保留對於不再需要的對象引用, 並且這組織了內存的垃圾收集器的工作. Java對象通常被其他對象包含引用, 為此一個單一對象可以保持整個對象樹在內存中, 於是導致了如下問題:
* 在向數組添加對象以后遺漏了對於他們的處理
* 直到你再次使用對象的時候都不釋放引用. 比如一個菜單指令可以插件一個對象實例引用並且不釋放便於以后再次調用的時候使用, 但是也許永遠不會發生.
* 在其他引用依然需要舊有狀態的時候貿然修改對象狀態. 比如當你為了在一個文本文件里面保存一些屬性而使用一個數組, 諸如”字符個數”等字段在不再需要的時候依然保留在內存當中.
* 允許一個長久執行的線程所引用的對象. 設置引用為NULL也無濟於事, 在線程退出和空閑之前, 對象不會被收集釋放
2.3 未釋放的系統資源
Java方法可以定位Java實例意外的堆內存, 諸如針對視窗和位圖的內存資源. Java常常通過JNI(Java Native Interface)調用C/C++子程序定位這些資源.
● 請說明一下垃圾回收的優點以及原理。
考察點:垃圾回收
參考回答:
Java 語言中一個顯著的特點就是引入了垃圾回收機制,使c++程序員最頭疼的內存管理的問題迎刃而解,它使得Java程序員在編寫程序的時候不再需要考慮內存管理。由於有個垃圾回收機制,Java中的對象不再有"作用域"的概念,只有對象的引用才有"作用域"。垃圾回收可以有效的防止內存泄露,有效的使用可以使用的內存。垃圾回收器通常是作為一個單獨的低級別的線程運行,不可預知的情況下對內存堆中已經死亡的或者長時間沒有使用的對象進行清楚和回收,程序員不能實時的調用垃圾回收器對某個對象或所有對象進行垃圾回收。回收機制有分代復制垃圾回收和標記垃圾回收,增量垃圾回收。
● 請問GC是什么? 還有為什么要有GC?
考察點:回收
參考回答:
GC是垃圾收集的意思(Gabage Collection),內存處理是編程人員容易出現問題的地方,忘記或者錯誤的內存回收會導致程序或系統的不穩定甚至崩潰,Java提供的GC功能可以自動監測對象是否超過作用域從而達到自動回收內存的目的,Java語言沒有提供釋放已分配內存的顯示操作方法。
● 請簡述一下GC算法
考察點:JVM
參考回答:
①GC(GarbageCollection 垃圾收集),GC的對象是堆空間和永久區
②GC算法包含:引用計數法,標記清除,標記壓縮,復制算法。
③引用計數器的實現很簡單,對於一個對象A,只要有任何一個對象引用了A,則A的引用計數器就加1,當引用失效時,引用計數器就減1。只要對象A的引用計數器的值為0,則對象A就不可能再被使用。
④標記-清除算法是現代垃圾回收算法的思想基礎。標記-清除算法將垃圾回收分為兩個階段:標記階段和清除階段。一種可行的實現是,在標記階段,首先通過根節點,標記所有從根節點開始的可達對象。因此,未被標記的對象就是未被引用的垃圾對象。然后,在清除階段,清除所有未被標記的對象。與標記-清除算法相比,復制算法是一種相對高效的回收方法不適用於存活對象較多的場合如老年代將原有的內存空間分為兩塊,每次只使用其中一塊,在垃圾回收時,將正在使用的內存中的存活對象復制到未使用的內存塊中,之后,清除正在使用的內存塊中的所有對象,交換兩個內存的角色,完成垃圾回收。
● 什么原因會導致minor gc運行頻繁?同樣的,什么原因又會導致minor gc運行很慢?請簡要說明一下
考察點:GC
參考回答:
可能是堆內存太小。
● 請問java中內存泄漏是什么意思?什么場景下會出現內存泄漏的情況?
考察點:內存泄漏
參考回答:
Java中的內存泄露,廣義並通俗的說,就是:不再會被使用的對象的內存不能被回收,就是內存泄露。如果長生命周期的對象持有短生命周期的引用,就很可能會出現內存泄露。