jvm是java虛擬機的縮寫。全部的java程序都是在jvm上運行的。作好jvm的優化能大大提高系統的性能java
大體流程如圖:編譯好的class文件經過類加載器從物理結構轉換成運行時數據區結構。再經過jvm內置執行引擎和本地方法的調用實現 ps:本地方法就是帶有native關鍵字的方法算法
其中方法區和堆是最重要的兩塊區域(這裏是以java7爲參照。java8沒有方法區)
由於這兩塊是gc算法做用的最主要區域windows
若是須要收集垃圾,則必須先找到垃圾。多線程
1.引用計數法併發
解釋:每一個對象都帶有一個引用計數器,當其餘聲明的變量指向這個對象時候,計數器就+1,當指向消逝時候,就將計數器-1.垃圾回收只回收計數爲0的對象。
缺點:沒法回收循環引用的狀況,好比A引用了B,B引用了C,C引用了A. 這種GC算法還須要編譯器進行配合,對對象引用進行計數,須要額外生成代碼。jvm
2.可達性分析性能
解釋:設立若干個根對象,當一個對象不能經過任何根對象引用達到,那麼這個對象在finalize中有一次能夠請求「重生」機會,或者直接忽略finalize,選擇直接死亡。 優化
找到垃圾後,開始垃圾收集spa
簡單解釋下:首先標記出全部須要回收的對象,在標記完成後統一回收掉全部被標記的對象。它的主要缺點有兩個:一個是效率問題,標記和清除過程的效率都不高;另一個是空間問題,標記清除以後會產生大量不連續的內存碎片,空間碎片太多可能會致使,當程序在之後的運行過程當中須要分配較大對象時沒法找到足夠的連續內存而不得不提早觸發另外一次垃圾收集動做線程
這是最基本的gc算法,後續的gc算法都是根據這種思路來改進的
標記過程仍然與「標記-清除」算法同樣,但後續步驟不是直接對可回收對象進行清理,而是讓全部存活的對象都向一端移動,而後直接清理掉端邊界之外的內存
將可用內存按容量劃分爲大小相等的兩塊,每次只使用其中的一塊。當這一塊的內存用完了,就將還存活着的對象複製到另一塊上面,而後再把已使用過的內存空間一次清理掉。
把Java堆分爲新生代和老年代,這樣就能夠根據各個年代的特色採用最適當的收集算法。在新生代中,每次垃圾收集時都發現有大批對象死去,只有少許存活,那就選用複製算法,只須要付出少許存活對象的複製成本就能夠完成收集。而老年代中由於對象存活率高、沒有額外空間對它進行分配擔保,就必須使用「標記-清理」或「標記-整理」算法來進行回收。
這裏總共會有三種gc
不一樣的gc使用不一樣的gc算法
注:默認新生代eden區和survivor區比例爲8:1:1
最早進的g1收集器使用的gc算法,相對於分代收集,它的分區處理更完全
在火車算法中,內存被分爲塊,多個塊組成一個集合。爲了形象化,一節車箱表明一個塊,一列火車表明一個集合,火車與車廂都按建立順序標號,每一個車箱大小相等,但每一個火車包含的車箱數不必定相等;每節車廂有一個被記憶集合,而每輛火車的記憶集合是它全部車箱記憶集合的總和;算法在執行時,要麼收集最小數字車箱,要麼收集最小數字火車。若是整節火車都是垃圾,就收集最小數字火車。
現有該場景
內存分爲四塊。 其中F,C,D,E是垃圾。G,A,B存活對象
首先掃描第一塊內存。發現G是存活對象,F是垃圾。利用記憶集合將G的應用存到最後一塊內存
回收第一塊內存
若是再次發生gc,則一樣掃描第二塊內存。發現A,B都是存活對象,都移到最後一塊內存。回收第二塊內存
由於火車算法是將一塊內存的對象移到另外一塊內存上並清除原來的內存。很像複製算法。
因此火車算法就被稱爲局部複製,外部標記清理
串行,stop the world
單cpu,新生代內存小,對暫停時間要求不高的應用
是client和32位windows的默認垃圾收集器
並行,stop the world
並行線程數默認值:cpu <= 8 則 線程數=cpu數 cpu>8 則(3+cpu*5)/8
可自定義線程數 :
多cpu,對暫停時間較短的應用
是server和2核cpu,2g內存的默認選擇
並行,stop the world
serial的多線程版
可搭配cms
不能搭配parllel old
多cpu,對暫停時間較短的應用
是server和2核cpu,2g內存的默認選擇
串行,stop the world ,標記整理算法,清除時間長
是client和32位windows的默認垃圾收集器
串行,stop the world ,標記整理算法
是server和2核cpu,2g內存的默認選擇
並行,併發,標記清理算法
默認併發線程數:(新生代並行線程數+3)/4
暫停時間短,很適用於追求高響應速度的互聯網引用
第一篇先到這兒了。先消化一下。後面再寫一篇關於調優的