java虛擬機(java virtual machine,JVM),一種可以運行java字節碼的虛擬機。
做爲一種編程語言的虛擬機,實際上不僅是專用於Java語言,只要生成的編譯文件匹配JVM對加載編譯文件格式要求,任何語言均可以由JVM編譯運行,好比kotlin、scala等。
jvm有不少,除了Hotspot,還有JRockit、J9等
複製代碼
JVM由三個主要的子系統構成: 類加載子系統、運行時數據區(內存結構)、執行引擎
複製代碼
當一個ClassLoader加載一個類的時候,除非顯示的使用另外一個ClassLoader,該類所依賴和引用的類也由這個
ClassLoader載入
複製代碼
指先委託父類加載器尋找目標類,在找不到的狀況下載本身的路徑中查找並載入目標類
雙親委派模式的優點
沙箱安全機制:好比本身寫的String.class類不會被加載,這樣能夠防止核心庫被隨意篡改
避免類的重複加載:當父ClassLoader已經加載了該類的時候,就不須要子ClassLoader再加載一次
複製代碼
類的全部字段和方法字節碼,以及一些特殊方法如構造函數,接口代碼在這裏定義。簡單來講,全部定義的方法的
信息都保存在該區域,靜態變量+常量+類信息(構造方法/接口定義)+運行時常量池都存在方法區中;
雖然Java虛擬機規範把方法區描述爲堆的一個邏輯部分,可是它卻有一個別名叫作Non-Heap(非堆),目的應該是爲了和Java的堆區分開;
複製代碼
虛擬機啓動時自動分配建立,用於存放對象的實例,幾乎全部對象都在堆上分配內存,當對象沒法在該空間申請到內存是將拋出OutOfMemoryError異常。同時也是垃圾收集器管理的主要區域。java
棧(Stack) Java線程執行方法的內存模型,一個線程對應一個棧,每一個方法在執行的同時都會建立一個棧幀(用於存儲局部變量表,操做數棧,動態連接,方法出口等信息)不存在垃圾回收問題,只要線程一結束該棧就釋放,生命週期和線程一致算法
本地方法棧(Native Method Stack) 和棧做用很類似,區別不過是Java棧爲JVM執行Java方法服務,而本地方法棧爲JVM執行native方法服務。登記native方法,在Execution Engine執行時加載本地方法庫編程
程序計數器(Program Counter Register) 就是一個指針,指向方法區中的方法字節碼(用來存儲指向嚇一跳指令的地址,也即將要執行的指令代碼),由執行引擎讀取下一條指令,是一個很是小的內存空間,幾乎能夠忽略不計瀏覽器
堆中幾乎放着全部的對象實例,對堆垃圾回收前的第一步就是要判斷哪些對象已經死亡(即不能再被任何途徑使用的對象)安全
引用計數法;bash
可達性分析算法服務器
運行時常量池主要回收的是廢棄的常量。那麼,咱們怎麼判斷一個常量時廢棄常量呢?多線程
須要知足如下三個條件:閉包
虛擬機能夠對知足上述3個條件的無用類進行回收,這裏僅僅是」能夠「,而並非和對象同樣不適用了就必然會被回收;併發
爲了解決效率問題,複製算法出現了。它能夠把內存分爲大小相同的兩塊,每次只使用其中的一塊。當這一塊的內存,使用完後,就將還存活的對象複製到另外一塊區,而後再把使用的空間一次清理掉。這樣就使每次的內存回收都是對內存區間的一半進行回收
根據老年代的特色提出的一種標記算法,標記過程和「標記-清除」算法同樣,可是後續步驟不是直接對可回收對象進行回收,而是讓全部存活的對象向一段移動,而後直接清理掉邊界之外的內存
如今的商用虛擬機的垃圾收集器基本都採用"分代收集"算法,這種算法就是根據對象存活週期的不一樣將內存分爲幾塊。通常將java堆分爲新生代和老年代,這樣咱們就能夠根據各個年代的特色選擇合適的垃圾收集算法。
Serial(串行)收集器收集器是最基本、歷史最悠久的垃圾收集器了。一個單線程收集器,它的 「單線程」 的意義不只僅意味着它只會使用一條垃圾收集線程去完成垃圾收集工做,更重要的是它在進行垃圾收集工做的時候必須暫停其餘全部的工做線程( 「Stop The World」 ),直到它收集結束。
Serial收集器的老年代版本,它一樣是一個單線程收集器。它主要有兩大用途:一種用途是在JDK1.5以及之前的版本中與Parallel Scavenge收集器搭配使用,另外一種用途是做爲CMS收集器的後備方案
Parallel Scavenge收集器的老年代版本。使用多線程和「標記-整理」算法。在注重吞吐量以及CPU資源的場合,均可以優先考慮 Parallel Scavenge收集器和Parallel Old收集器。
CMS(Concurrent Mark Sweep)收集器是一種以獲取最短回收停頓時間爲目標的收集器。它而很是符合在注重用戶體驗的應用上使用。
CMS(Concurrent Mark Sweep)收集器是HotSpot虛擬機第一款真正意義上的併發收集器,它第一次實現了讓垃圾收集線程與用戶線程(基本上)同時工做。
從名字中的Mark Sweep這兩個詞能夠看出,CMS收集器是一種 「標記-清除」算法實現的,它的運做過程相比於前面幾種垃圾收集器來講更加複雜一些。整個過程分爲四個步驟:
CMS主要優勢:併發收集、低停頓。可是它有下面三個明顯的缺點:
G1 (Garbage-First)是一款面向服務器的垃圾收集器,主要針對配備多顆處理器及大容量內存的機器. 以極高機率知足,GC停頓時間要求的同時,還具有高吞吐量性能特徵; 被視爲JDK1.7中HotSpot虛擬機的一個重要進化特徵。它具有一下特色:
並行與併發:G1能充分利用CPU、多核環境下的硬件優點,使用多個CPU(CPU或者CPU核心)來縮短StopThe-World停頓時間。部分其餘收集器本來須要停頓Java線程執行的GC動做,G1收集器仍然能夠經過併發的方式讓java程序繼續執行
分代收集:雖然G1能夠不須要其餘收集器配合就能獨立管理整個GC堆,可是仍是保留了分代的概念。 空間整合:與CMS的「標記–清理」算法不一樣,G1從總體來看是基於「標記整理」算法實現的收集器;從局部上來看是基於「複製」算法實現的
可預測的停頓:這是G1相對於CMS的另外一個大優點,下降停頓時間是G1 和 CMS 共同的關注點,但G1 除了追求低停頓外,還能創建可預測的停頓時間模型,能讓使用者明確指定在一個長度爲M毫秒的時間片斷內
G1收集器的運做大體分爲如下幾個步驟:
G1收集器在後臺維護了一個優先列表,每次根據容許的收集時間,優先選擇回收價值最大的Region(這也就是它的名字Garbage-First的由來)。這種使用Region劃份內存空間以及有優先級的區域回收方式,保證了GF收集器在有限時間內能夠儘量高的收集效率(把內存化整爲零)
即ZGC,是一個可伸縮的、低延遲的垃圾收集器,主要爲了知足以下目標進行設計: 停頓時間不會超過10ms 停頓時間不會隨着堆的增大而增大(無論多大的堆都能保持在10ms如下) 可支持幾百M,甚至幾T的堆大小(最大支持4T) 停頓時間在10ms如下,10ms實際上是一個很保守的數據,在SPECjbb 2015基準測試,128G的大堆下最大停頓時間才1.68ms,遠低於10ms;
The Z Garbage Collector, also known as ZGC, is a scalable low latency garbage collector designed to meet the following goals:
Pause times do not exceed 10ms
Pause times do not increase with the heap or live-set size
Handle heaps ranging from a few hundred megabytes to multi terabytes in size
複製代碼
JVM調優主要就是調整下面兩個指標
-Xss:每一個線程的棧大小 -Xms:初始堆大小,默認物理內存的1/64 -Xmx:最大堆大小,默認物理內存的1/4 -Xmn:新生代大小 -XX:NewSize:設置新生代初始大小-XX:NewRatio:默認2表示新生代佔年老代的1/2,佔整個堆內存的1/3。 -XX:SurvivorRatio:默認8表示一個survivor區佔用1/8的Eden內存,即1/10的新生代內存。 -XX:MetaspaceSize:設置元空間大小 -XX:MaxMetaspaceSize:設置元空間最大容許大小,默認不受限制,JVM Metaspace會進行動態擴展
-XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:filename
-XX:+UseSerialGC:設置串行收集器 -XX:+UseParallelGC:設置並行收集器 -XX:+UseParallelOldGC:老年代使用並行回收收集器 -XX:+UseParNewGC:在新生代使用並行收集器 -XX:+UseParalledlOldGC:設置並行老年代收集器 -XX:+UseConcMarkSweepGC:設置CMS併發收集器 -XX:+UseG1GC:設置G1收集器 -XX:ParallelGCThreads:設置用於垃圾回收的線程數
-XX:ParallelGCThreads:設置並行收集器收集時使用的CPU數。並行收集線程數。 -XX:MaxGCPauseMillis:設置並行收集最大暫停時間 -XX:GCTimeRatio:設置垃圾回收時間佔程序運行時間的百分比。公式爲1/(1+n)
-XX:+UseConcMarkSweepGC:設置CMS併發收集器 -XX:+CMSIncrementalMode:設置爲增量模式。適用於單CPU狀況。 -XX:ParallelGCThreads:設置併發收集器新生代收集方式爲並行收集時,使用的CPU數。並行收集線程數。 -XX:CMSFullGCsBeforeCompaction:設定進行多少次CMS垃圾回收後,進行一次內存壓縮 -XX:+CMSClassUnloadingEnabled:容許對類元數據進行回收 -XX:UseCMSInitiatingOccupancyOnly:表示只在到達閥值的時候,才進行CMS回收 -XX:+CMSIncrementalMode:設置爲增量模式。適用於單CPU狀況 -XX:ParallelCMSThreads:設定CMS的線程數量 -XX:CMSInitiatingOccupancyFraction:設置CMS收集器在老年代空間被使用多少後觸發 -XX:+UseCMSCompactAtFullCollection:設置CMS收集器在完成垃圾收集後是否要進行一次內存碎片的整理
-XX:+UseG1GC:使用G1收集器 -XX:ParallelGCThreads:指定GC工做的線程數量 -XX:G1HeapRegionSize:指定分區大小(1MB~32MB,且必須是2的冪),默認將整堆劃分爲2048個分區 -XX:GCTimeRatio:吞吐量大小,0-100的整數(默認9),值爲n則系統將花費不超過1/(1+n)的時間用於垃圾收集 -XX:MaxGCPauseMillis:目標暫停時間(默認200ms) -XX:G1NewSizePercent:新生代內存初始空間(默認整堆5%) -XX:G1MaxNewSizePercent:新生代內存最大空間 -XX:TargetSurvivorRatio:Survivor填充容量(默認50%) -XX:MaxTenuringThreshold:最大任期閾值(默認15) -XX:InitiatingHeapOccupancyPercen:老年代佔用空間超過整堆比IHOP閾值(默認45%),超過則執行混合收集 -XX:G1HeapWastePercent:堆廢物百分比(默認5%) -XX:G1MixedGCCountTarget:參數混合週期的最大總次數(默認8