1、哪些內存能夠回收算法
JVM 的內存區域中,程序計數器、虛擬機棧和本地方法棧這 3 個區域是線程私有的,隨着線程的建立而建立,銷燬而銷燬,所以不用回收。安全
垃圾回收的重點就是關注堆和方法區中的內存了,堆中的回收主要是對象的回收,方法區的回收主要是廢棄常量和無用的類的回收。併發
2、何時能夠被回收oracle
通常一個對象再也不被引用,就表明該對象能夠被回收。目前有如下兩種算法能夠判斷該對象是否能夠被回收:工具
一、引用計數算法性能
這種算法是經過一個對象的引用計數器來判斷該對象是否被引用了。每當對象被引用,引用計數器就會加 1;每當引用失效,計數器就會減 1。優化
當對象的引用計數器的值爲 0 時,就說明該對象再也不被引用,能夠被回收了。spa
雖然引用計數算法的實現簡單,判斷效率也很高,但它存在着對象之間相互循環引用的問題。線程
二、可達性分析算法日誌
GC Roots 是全部對象的根引用。在垃圾回收時,會從這些 GC Roots 開始向下搜索,當一個對象到 GC Roots 沒有任何引用鏈相連時,就證實此對象能夠被回收。
目前 HotSpot 虛擬機採用的就是這種算法。
2.一、可做爲GC Roots的對象:
Java虛擬機棧中的引用的對象 ;本地方法棧中JNI的引用的對象 ;方法區中的類靜態屬性、常量對象 。
以上兩種算法都是經過引用來判斷對象是否能夠被回收。在 JDK 1.2 以後,Java 對引用的概念進行了擴充,將引用分爲了如下四種:
3、回收算法
4、回收器/類型
5、GC 性能衡量指標
吞吐量:這裏的吞吐量是指應用程序所花費的時間和系統總運行時間的比值。咱們能夠按照這個公式來計算 GC 的吞吐量:系統總運行時間 = 應用程序耗時 +GC 耗時。若是系統運行了 100 分鐘,GC 耗時 1 分鐘,則系統吞吐量爲 99%。
停頓時間:指垃圾收集器正在運行時,應用程序的暫停時間。對於串行回收器而言,停頓時間可能會比較長;而使用併發回收器,因爲垃圾收集器和應用程序交替運行,程序的停頓時間就會變短,但其效率極可能不如獨佔垃圾收集器,系統的吞吐量也極可能會下降。
6、查看 & 分析 GC 日誌
首先,咱們須要經過 JVM 參數預先設置 GC 日誌,一般有如下幾種 JVM 參數設置:
-XX:+PrintGC 輸出 GC 日誌
-XX:+PrintGCDetails 輸出 GC 的詳細日誌
-XX:+PrintGCTimeStamps 輸出 GC 的時間戳(以基準時間的形式)
-XX:+PrintGCDateStamps 輸出 GC 的時間戳(以日期的形式,如 2013-05-04T21:53:59.234+0800)
-XX:+PrintHeapAtGC 在進行 GC 的先後打印出堆的信息
-Xloggc:../logs/gc.log 日誌文件的輸出路徑
eg:-XX:+PrintGCTimeStamps -XX:+PrintGCDetails -Xloggc:/log/heapTest.log
若是GC日誌很是大,能夠用GCViewer工具打開日誌文件,圖形化界面查看總體的 GC 性能,以下圖所示:
也能夠用GCeasy工具,而且還能夠將日誌文件壓縮以後,上傳到 GCeasy 官網便可看到很是清楚的 GC 日誌分析結果
7、回收調優
1. 下降 Minor GC 頻率
Eden區存活的對象數量小,能夠經過增大新生代空間來下降 Minor GC 的頻率。
一般狀況下,因爲新生代空間較小,Eden 區很快被填滿,就會致使頻繁 Minor GC,所以咱們能夠經過增大新生代空間來下降 Minor GC 的頻率。
可能你會有這樣的疑問,擴容 Eden 區雖然能夠減小 Minor GC 的次數,但不會增長單次 Minor GC 的時間嗎?若是單次 Minor GC 的時間增長,那也很難達到咱們期待的優化效果呀。
若是在堆內存中存在較多的長期存活的對象,此時增長年輕代空間,反而會增長 Minor GC 的時間。若是堆中的短時間對象不少,那麼擴容新生代,單次 Minor GC 時間不會顯著增長。所以,單次 Minor GC 時間更多取決於 GC 後存活對象的數量,而非 Eden 區的大小。
二、下降 Full GC 的頻率
2.一、減小建立大對象
2.二、增大堆內存空間
2.三、選擇合適的 GC 回收器
垃圾收集器的種類不少,咱們能夠將其分紅兩種類型,一種是響應速度快,一種是吞吐量高。一般狀況下,CMS (Concurrent Mark Sweep)和 G1 回收器的響應速度快,Parallel Scavenge 回收器的吞吐量高。
ps1:首先cms在1.9已經被標記爲廢棄,主要緣由在於標記清除下的懸浮內存,致使內存空間碎片化,進而致使fullGC的發生。不過其並行執行垃圾回收的性能仍是值得承認的,至少1.9後主推的G1在常規狀況下也是不如它的效率好的。
ps2:G1與CMS的優點在於如下幾點:
一、並行與併發:G1可以更充分利用多CPU、多核環境運行
二、分代收集:G1雖然也用了分代概念,但相比其餘收集器須要配合不一樣收集協同工做,但G1收集器可以獨立管理整個堆
三、空間管理:與CMS的標記一清理算法不一樣,G1從總體上基於標記一整理算法,將整個Java堆劃分爲多個大小相等的獨立區域(Region),這種算法可以在運行過程當中不產生內存碎片
四、可預測的停頓:下降停頓時間是G1和CMS共同目標,可是G1追求低停頓外,還能創建可預測的停頓時間模型,能讓使用者明確指定一個長度爲M毫秒的時間片斷內,消耗在垃圾收集器上的時間不得超過N毫秒。
eg:經過XX:MaxGCPauseMillis =500能夠設置full gc 穩定在500ms之內
ps3:oracle一些1.9 10 11 12的特性都有以補丁的方式落到1.8。因此1.8仍是比較安全實用的