垃圾回收是JAVA中的一個大知識點,也是一個著名知識點,畢竟JAVA號稱自己先進性的時候總是會帶上垃圾回收。於是,它也成了面試中的常客,面試官動不動的就要你解釋下什麼是垃圾回收,以及它的原理是什麼。當然,雖然,以及肯定,那個問你垃圾回收的面試官他99%也只是略知皮毛而已。當面試官問你什麼是垃圾回收機制的時候,你應該這樣一本正經的反問:請問您問的哪個VM中的垃圾回收機制?
由於垃圾回收涉及的概念複雜,演算法複雜,你若想弄清楚其中的全部細節,必定得不償失。但是,如果我們掌握了以下的垃圾回收機制的概要,相信在絕大部分的面試中你不會失分。
一:什麼是垃圾?
舉例來說,一個物件你不用了,它就是垃圾,例如:
public void test01(){
User user = new User();
//...
}
test01方法執行完畢,user物件沒有任何用處了,那它就是垃圾了。
二:為什麼要進行垃圾回收?
我們知道,物件是存放在堆上的,那麼堆有多大?雖然可以透過指令參數進行調整,但是通常情況下,32位元系統下,Java堆大小設定在2 GB其中,500 MB 分配給新生代(YoungGen)1.5 GB的分配給老年代(OldGen)空間。即便64位,想想我們PC的硬體記憶體能有多大。
所以,沒用的垃圾,統統回收,讓出記憶體空間,給其它物件用。
三:JDK預設的HotSpot VM垃圾回收的機制
1:堆記憶體的分類
#要理解這個機制,首先得明白堆的分類。是的,我們光知道物件存在於堆上,但不知道堆內部也分成幾個空間,如下圖:
Young/New Generation 新生代
其內部又分為Eden 與兩個Survivor Space 組成。新建的物件都將分配到新生代中,
Old/Tenured Generation 老年代
舊年代用於存放程序中經過幾次垃圾回收後存活的物件
(PS:Permanent Generation 非堆疊內存,用於存放靜態文件,如Java類別、方法等。持久代對垃圾回收沒有顯著影響。)
2:回收順序
每個空間的執行順序如下:
四:垃圾收集器與回收演算法
兩種類型的代都有自己的收集器,每種收集器採用不同的演算法。請記住,對於初級選手,我們並不需要掌握每個演算法原理。 新生代收集器使用的收集器:Serial、PraNew、Parallel Scavenge老年代收集器使用的收集器:Serial Old、Parallel Old、CMS#其對應的演算法如下,Serial收集器(複製演算法)
#新生代單執行緒收集器,標記和清理都是單線程,優點是簡單且有效率。Serial Old收集器(標記-整理演算法)
老年代單執行緒收集器,Serial收集器的老年代版本。ParNew收集器(停止-複製演算法)
新生代收集器,可以認為是Serial收集器的多執行緒版本,在多核心CPU環境下有著比Serial更好的表現。Parallel Scavenge收集器(停止-複製演算法)
#並行收集器,追求高吞吐量,高效利用CPU。吞吐量一般為99%,吞吐量= 使用者執行緒時間/(使用者執行緒時間+GC執行緒時間)。適合後台應用程式等對互動相應要求不高的場景。Parallel Old收集器(停止-複製演算法)
Parallel Scavenge收集器的老年代版本,並行收集器,吞吐量優先#CMS(Concurrent Mark Sweep)收集器(標記-清理演算法)
高併發、低停頓,追求最短GC回收停頓時間,cpu佔用比較高,反應時間快,停頓時間短,多核心cpu 追求高反應時間的選擇
#五:什麼時候會運行垃圾回收?
垃圾回收有兩種類型,Scavenge GC和Full GC。
當新物件生成,並且在Eden申請空間失敗時,就會觸發Scavenge GC。此時會對新生代進行垃圾回收。
當,年老代(Tenured)被寫滿、持久代(Perm)被寫滿、System.gc()被顯示調用、上一次GC之後Heap的各域分配策略動態變化,執行Full GC。
注意,無論是那種回收,並不意味著會把全部的垃圾回收掉,而是根據演算法自己的判斷,在一段時間內除掉一定數量的垃圾,這個時間和數量我們不可知。
以上,就是你必須知道的垃圾回收機制。
以上是JAVA垃圾回收機制的詳細內容。更多資訊請關注PHP中文網其他相關文章!