程序計數器java
Java虛擬機棧程序員
本地方法棧算法
Java堆(GC區)(Java Head)數組
JDK1.7 方法區(永久代)安全
用於存放已被加載的類信息、常量、靜態變量、即時編譯器編譯後的代碼等數據。 對這塊區域進行垃圾回收的主要目的是對常量池的回收和對類的卸載,可是通常難以實現。 HotSpot虛擬機把它當作永久代來進行垃圾回收。但很難肯定永久代的大小,由於它受到不少因素的影響,而且每次Full GC以後永久代的大小都會改變,因此常常拋出OOM異常。 從JDK1.8開始,移除永久代,並把方法區移至元空間。數據結構
運行時常量池多線程
JDK1.8 元空間併發
直接內存函數
句柄訪問佈局
直接指針訪問(HotSpot使用)
第一次標記(緩刑)
引用計數算法
可是它難以解決對象之間的相互循環引用的狀況,此時這個兩個對象引用計數值爲1,可是永遠沒法用到這兩個對象。
- 可達性分析算法(Java使用)
- 以一系列GC Roots的對象做爲起始點,從這些節點開始向下搜索,搜索所走過的路徑稱爲引用鏈,當一個對象到GC Roots沒有任何引用鏈相連是,則證實此對象不可用,能夠被回收。
複製代碼
GC Roots對象包括
第二次標記
當對象沒有覆蓋finalize()方法,或者finalize()方法已經被虛擬機調用過。 若是對象在finalize方法中從新與引用鏈上的任何一個對象創建關聯則將不會被回收。
finalize()
知足無用的類三個判斷條件才僅僅表明能夠進行回收,不是必然關係,可使用-Xnoclassgc參數控制。
不足:
如今商業虛擬機都採用這種算法用於新生代。 由於新生代中的對象98%都是朝生暮死,因此將內存分爲一塊較大的Eden空間和兩塊較小的Survivor空間,每次使用Eden和其中一塊Survivor空間。 當回收時,若是另一塊Survivor空間沒有足夠的空間存放存活下來的對象時,這些對象將直接經過分配擔保機制進入老年代。
枚舉根節點(GC Roots)
安全點
程序執行只有到達安全點時才能暫停,到達安全點有兩種方案。
可是當線程sleep或blocked時沒法響應JVM的中斷請求走到安全點中斷掛起,因此引出安全區域。
安全區域
線程進入安全區域時表示本身進入了安全區域,這個發生GC時,JVM就不須要管這個線程。 線程離開安全區域時,檢查系統是否完成GC過程,沒有就等待能夠離開安全區域的信號爲止,否者繼續執行。
新生代
優勢:對比其餘單線程收集器簡單高效,對於單個CPU環境來講,沒有線程交互的開銷,所以擁有最高的單線程收集效率。
它是Client場景下默認新生代收集器,由於在該場景下內存通常來講不會很大。
- 2. parnew收集器
- 它是Serial收集器的多線程版本,公用了至關多的代碼。
複製代碼
在單CPU環境中絕對不會有比Serial收集器更好的效果,甚至在2個CPU環境中也不能百分之百超越。
它是Server場景下默認的新生代收集器,主要由於除了Serial收集器,只用它能與CMS收集器配合使用。
- 3. parallel scavenge收集器
- 「吞吐優先」收集器,與ParNew收集器差很少。
複製代碼
可是其餘收集器的目標是儘量縮短垃圾收集時用戶線程停頓的時間,而它的目標是達到一個可控制的吞吐量。這裏的吞吐量指CPU用於運行用戶程序的時間佔總時間的比值。
老年代
也是給Client場景下的虛擬機使用的。
- 5. parallel old收集器
- 是Parallel Scavenge收集器的老年代版本。
複製代碼
在注重吞吐量已經CPU資源敏感的場合,均可以優先考慮Parallel Scavenge和Parallel Old收集器。
- 6. cms收集器
- Concurrent Mark Sweep收集器是一種以獲取最短回收停頓時間爲目標的收集器。
- 運做過程
- 1. 初始標記(最短)。仍須要暫停用戶線程。只是標記一下GC Roots能直接關聯到的對象,速度很快
複製代碼
1 和4 兩個步驟並無帶上併發兩個字,即這兩個步驟仍要暫停用戶線程。
- 優缺點
- 併發收集、低停頓。
複製代碼
Garbage First是一款面向服務端應用的垃圾收集器
運做過程
主動引用
被動引用
初始化階段才真正執行類中定義的Java程序代碼,是執行類構造器()方法的過程。 在準備階段,類變量已經給過零值,而在初始化階段,根據程序員經過程序制定的主觀計劃去初始化類變量和其餘資源。
()
不須要顯式調用父類構造器,JVM會保證在子類clinit執行以前,父類的clinit已經執行完成。
接口中不能使用靜態語句塊但仍能夠有類變量的賦值操做。當沒有使用父接口中定義的變量時子接口的clinit不須要先執行父接口的clinit方法。接口的實現類也不會執行接口的clinit方法。
虛擬機會保證clinit在多線程環境中被正確的加鎖、同步。其餘線性喚醒以後不會再進入clinit方法,同一個類加載器下,一個類型只會初始化一次。
- <init>()
- 對象構造器方法。Java對象被建立時纔會進行實例化操做,對非靜態變量解析初始化。
複製代碼
會顯式的調用父類的init方法,對象實例化過程當中對實例域的初始化操做所有在init方法中進行。
類與類加載器
類加載器分類
啓動類加載器
擴展類加載器
應用程序類加載器
自定義類加載器
雙親委派模型
雙親委派模型要求除了頂層的啓動類加載器外,其他的類加載器都應該有本身的父類加載器。父子不會以繼承的關係類實現,而是都是使用組合關係來服用父加載器的代碼。 在java.lang.ClassLoader的loadClass()方法中實現。
工做過程
好處
Minor GC
發生在新生代的垃圾收集動做,由於新生代對象存活時間很短,所以Minor GC會頻繁執行,執行速度快。
時機
Full GC
發生在老年區的GC,出現Full GC時每每伴隨着Minor GC,比Minor GC慢10倍以上。
時機