'詳解JAVA的GC機制與JVM優化參數總結'

"

概述

JAVA提供了垃圾回收器(garbage collector)來自動檢測對象的作用域),可自動把不再被使用的存儲空間釋放掉,也就是說,GC機制可以有效地防止內存洩露以及內存溢出。


GC任務

JAVA 垃圾回收器的主要任務是:

  • 分配內存
  • 確保被引用對象的內存不被錯誤地回收
  • 回收不再被引用的對象的內存空間

凡事都有兩面性。垃圾回收器在把程序員從釋放內存的複雜工作中解放出來的同時,為了實現垃圾回收,garbage collector必須跟蹤內存的使用情況,釋放沒用的對象,在完成內存的釋放之後還需要處理堆中的碎片, 這樣做必定會增加JVM的負擔。


JAVA 內存區域

先看看JAVA程序在執行的時候,內存究竟是如何劃分的。

"

概述

JAVA提供了垃圾回收器(garbage collector)來自動檢測對象的作用域),可自動把不再被使用的存儲空間釋放掉,也就是說,GC機制可以有效地防止內存洩露以及內存溢出。


GC任務

JAVA 垃圾回收器的主要任務是:

  • 分配內存
  • 確保被引用對象的內存不被錯誤地回收
  • 回收不再被引用的對象的內存空間

凡事都有兩面性。垃圾回收器在把程序員從釋放內存的複雜工作中解放出來的同時,為了實現垃圾回收,garbage collector必須跟蹤內存的使用情況,釋放沒用的對象,在完成內存的釋放之後還需要處理堆中的碎片, 這樣做必定會增加JVM的負擔。


JAVA 內存區域

先看看JAVA程序在執行的時候,內存究竟是如何劃分的。

詳解JAVA的GC機制與JVM優化參數總結

私有內存區的區域名稱和相應的特性如下表所示:

"

概述

JAVA提供了垃圾回收器(garbage collector)來自動檢測對象的作用域),可自動把不再被使用的存儲空間釋放掉,也就是說,GC機制可以有效地防止內存洩露以及內存溢出。


GC任務

JAVA 垃圾回收器的主要任務是:

  • 分配內存
  • 確保被引用對象的內存不被錯誤地回收
  • 回收不再被引用的對象的內存空間

凡事都有兩面性。垃圾回收器在把程序員從釋放內存的複雜工作中解放出來的同時,為了實現垃圾回收,garbage collector必須跟蹤內存的使用情況,釋放沒用的對象,在完成內存的釋放之後還需要處理堆中的碎片, 這樣做必定會增加JVM的負擔。


JAVA 內存區域

先看看JAVA程序在執行的時候,內存究竟是如何劃分的。

詳解JAVA的GC機制與JVM優化參數總結

私有內存區的區域名稱和相應的特性如下表所示:

詳解JAVA的GC機制與JVM優化參數總結

這裡主要說一下虛擬機棧中的局部變量表,裡面存放了三個信息:

  • 各種基本數據類型(boolean、byte、char、short、int、float、long、double)
  • 對象引用(reference)
  • returnAddress地址

這個returnAddress和程序計數器有什麼區別?前者是指示JVM的指令執行到哪一行,後者則是代碼執行到哪一行。

私有內存區伴隨著線程的產生而產生,一旦線程中止,私有內存區也會自動消除。

"

概述

JAVA提供了垃圾回收器(garbage collector)來自動檢測對象的作用域),可自動把不再被使用的存儲空間釋放掉,也就是說,GC機制可以有效地防止內存洩露以及內存溢出。


GC任務

JAVA 垃圾回收器的主要任務是:

  • 分配內存
  • 確保被引用對象的內存不被錯誤地回收
  • 回收不再被引用的對象的內存空間

凡事都有兩面性。垃圾回收器在把程序員從釋放內存的複雜工作中解放出來的同時,為了實現垃圾回收,garbage collector必須跟蹤內存的使用情況,釋放沒用的對象,在完成內存的釋放之後還需要處理堆中的碎片, 這樣做必定會增加JVM的負擔。


JAVA 內存區域

先看看JAVA程序在執行的時候,內存究竟是如何劃分的。

詳解JAVA的GC機制與JVM優化參數總結

私有內存區的區域名稱和相應的特性如下表所示:

詳解JAVA的GC機制與JVM優化參數總結

這裡主要說一下虛擬機棧中的局部變量表,裡面存放了三個信息:

  • 各種基本數據類型(boolean、byte、char、short、int、float、long、double)
  • 對象引用(reference)
  • returnAddress地址

這個returnAddress和程序計數器有什麼區別?前者是指示JVM的指令執行到哪一行,後者則是代碼執行到哪一行。

私有內存區伴隨著線程的產生而產生,一旦線程中止,私有內存區也會自動消除。

詳解JAVA的GC機制與JVM優化參數總結


JAVA堆

堆內存是由存活和死亡的對象組成的。存活的對象是應用可以訪問的,不會被垃圾回收。死亡的對象是應用不可訪問尚且還沒有被垃圾收集器回收掉的對象。一直到垃圾收集器把這些對象回收掉之前,他們會一直佔據堆內存空間。

堆是應用程序在運行期請求操作系統分配給自己的向高地址擴展的數據結構,是不連續的內存區域。用一句話總結堆的作用:程序運行時動態申請某個大小的內存空間

"

概述

JAVA提供了垃圾回收器(garbage collector)來自動檢測對象的作用域),可自動把不再被使用的存儲空間釋放掉,也就是說,GC機制可以有效地防止內存洩露以及內存溢出。


GC任務

JAVA 垃圾回收器的主要任務是:

  • 分配內存
  • 確保被引用對象的內存不被錯誤地回收
  • 回收不再被引用的對象的內存空間

凡事都有兩面性。垃圾回收器在把程序員從釋放內存的複雜工作中解放出來的同時,為了實現垃圾回收,garbage collector必須跟蹤內存的使用情況,釋放沒用的對象,在完成內存的釋放之後還需要處理堆中的碎片, 這樣做必定會增加JVM的負擔。


JAVA 內存區域

先看看JAVA程序在執行的時候,內存究竟是如何劃分的。

詳解JAVA的GC機制與JVM優化參數總結

私有內存區的區域名稱和相應的特性如下表所示:

詳解JAVA的GC機制與JVM優化參數總結

這裡主要說一下虛擬機棧中的局部變量表,裡面存放了三個信息:

  • 各種基本數據類型(boolean、byte、char、short、int、float、long、double)
  • 對象引用(reference)
  • returnAddress地址

這個returnAddress和程序計數器有什麼區別?前者是指示JVM的指令執行到哪一行,後者則是代碼執行到哪一行。

私有內存區伴隨著線程的產生而產生,一旦線程中止,私有內存區也會自動消除。

詳解JAVA的GC機制與JVM優化參數總結


JAVA堆

堆內存是由存活和死亡的對象組成的。存活的對象是應用可以訪問的,不會被垃圾回收。死亡的對象是應用不可訪問尚且還沒有被垃圾收集器回收掉的對象。一直到垃圾收集器把這些對象回收掉之前,他們會一直佔據堆內存空間。

堆是應用程序在運行期請求操作系統分配給自己的向高地址擴展的數據結構,是不連續的內存區域。用一句話總結堆的作用:程序運行時動態申請某個大小的內存空間

詳解JAVA的GC機制與JVM優化參數總結

新生代:剛剛新建的對象在Eden中,經歷一次Minor GC,Eden中的存活對象就會被移動到第一塊survivor space S0,Eden被清空;等Eden區再滿了,就再觸發一次Minor GC,Eden和S0中的存活對象又會被複制送入第二塊survivor space S1。S0和Eden被清空,然後下一輪S0與S1交換角色,如此循環往復。如果對象的複製次數達到16次,該對象就會被送到老年代中。

老年代:如果某個對象經歷了幾次垃圾回收之後還存活,就會被存放到老年代中。老年代的空間一般比新生代大。

"

概述

JAVA提供了垃圾回收器(garbage collector)來自動檢測對象的作用域),可自動把不再被使用的存儲空間釋放掉,也就是說,GC機制可以有效地防止內存洩露以及內存溢出。


GC任務

JAVA 垃圾回收器的主要任務是:

  • 分配內存
  • 確保被引用對象的內存不被錯誤地回收
  • 回收不再被引用的對象的內存空間

凡事都有兩面性。垃圾回收器在把程序員從釋放內存的複雜工作中解放出來的同時,為了實現垃圾回收,garbage collector必須跟蹤內存的使用情況,釋放沒用的對象,在完成內存的釋放之後還需要處理堆中的碎片, 這樣做必定會增加JVM的負擔。


JAVA 內存區域

先看看JAVA程序在執行的時候,內存究竟是如何劃分的。

詳解JAVA的GC機制與JVM優化參數總結

私有內存區的區域名稱和相應的特性如下表所示:

詳解JAVA的GC機制與JVM優化參數總結

這裡主要說一下虛擬機棧中的局部變量表,裡面存放了三個信息:

  • 各種基本數據類型(boolean、byte、char、short、int、float、long、double)
  • 對象引用(reference)
  • returnAddress地址

這個returnAddress和程序計數器有什麼區別?前者是指示JVM的指令執行到哪一行,後者則是代碼執行到哪一行。

私有內存區伴隨著線程的產生而產生,一旦線程中止,私有內存區也會自動消除。

詳解JAVA的GC機制與JVM優化參數總結


JAVA堆

堆內存是由存活和死亡的對象組成的。存活的對象是應用可以訪問的,不會被垃圾回收。死亡的對象是應用不可訪問尚且還沒有被垃圾收集器回收掉的對象。一直到垃圾收集器把這些對象回收掉之前,他們會一直佔據堆內存空間。

堆是應用程序在運行期請求操作系統分配給自己的向高地址擴展的數據結構,是不連續的內存區域。用一句話總結堆的作用:程序運行時動態申請某個大小的內存空間

詳解JAVA的GC機制與JVM優化參數總結

新生代:剛剛新建的對象在Eden中,經歷一次Minor GC,Eden中的存活對象就會被移動到第一塊survivor space S0,Eden被清空;等Eden區再滿了,就再觸發一次Minor GC,Eden和S0中的存活對象又會被複制送入第二塊survivor space S1。S0和Eden被清空,然後下一輪S0與S1交換角色,如此循環往復。如果對象的複製次數達到16次,該對象就會被送到老年代中。

老年代:如果某個對象經歷了幾次垃圾回收之後還存活,就會被存放到老年代中。老年代的空間一般比新生代大。

詳解JAVA的GC機制與JVM優化參數總結

不過實際運行中,Major GC會伴隨至少一次 Minor GC,因此也不必過多糾結於到底是哪種GC(在有些資料中看到把full GC和Minor GC等價的說法)。

那麼,當我們創建一個對象後,它會被放在堆內存的哪個部分呢?

"

概述

JAVA提供了垃圾回收器(garbage collector)來自動檢測對象的作用域),可自動把不再被使用的存儲空間釋放掉,也就是說,GC機制可以有效地防止內存洩露以及內存溢出。


GC任務

JAVA 垃圾回收器的主要任務是:

  • 分配內存
  • 確保被引用對象的內存不被錯誤地回收
  • 回收不再被引用的對象的內存空間

凡事都有兩面性。垃圾回收器在把程序員從釋放內存的複雜工作中解放出來的同時,為了實現垃圾回收,garbage collector必須跟蹤內存的使用情況,釋放沒用的對象,在完成內存的釋放之後還需要處理堆中的碎片, 這樣做必定會增加JVM的負擔。


JAVA 內存區域

先看看JAVA程序在執行的時候,內存究竟是如何劃分的。

詳解JAVA的GC機制與JVM優化參數總結

私有內存區的區域名稱和相應的特性如下表所示:

詳解JAVA的GC機制與JVM優化參數總結

這裡主要說一下虛擬機棧中的局部變量表,裡面存放了三個信息:

  • 各種基本數據類型(boolean、byte、char、short、int、float、long、double)
  • 對象引用(reference)
  • returnAddress地址

這個returnAddress和程序計數器有什麼區別?前者是指示JVM的指令執行到哪一行,後者則是代碼執行到哪一行。

私有內存區伴隨著線程的產生而產生,一旦線程中止,私有內存區也會自動消除。

詳解JAVA的GC機制與JVM優化參數總結


JAVA堆

堆內存是由存活和死亡的對象組成的。存活的對象是應用可以訪問的,不會被垃圾回收。死亡的對象是應用不可訪問尚且還沒有被垃圾收集器回收掉的對象。一直到垃圾收集器把這些對象回收掉之前,他們會一直佔據堆內存空間。

堆是應用程序在運行期請求操作系統分配給自己的向高地址擴展的數據結構,是不連續的內存區域。用一句話總結堆的作用:程序運行時動態申請某個大小的內存空間

詳解JAVA的GC機制與JVM優化參數總結

新生代:剛剛新建的對象在Eden中,經歷一次Minor GC,Eden中的存活對象就會被移動到第一塊survivor space S0,Eden被清空;等Eden區再滿了,就再觸發一次Minor GC,Eden和S0中的存活對象又會被複制送入第二塊survivor space S1。S0和Eden被清空,然後下一輪S0與S1交換角色,如此循環往復。如果對象的複製次數達到16次,該對象就會被送到老年代中。

老年代:如果某個對象經歷了幾次垃圾回收之後還存活,就會被存放到老年代中。老年代的空間一般比新生代大。

詳解JAVA的GC機制與JVM優化參數總結

不過實際運行中,Major GC會伴隨至少一次 Minor GC,因此也不必過多糾結於到底是哪種GC(在有些資料中看到把full GC和Minor GC等價的說法)。

那麼,當我們創建一個對象後,它會被放在堆內存的哪個部分呢?

詳解JAVA的GC機制與JVM優化參數總結

如果Major GC之後還是老年代不足,那JVM就會拋出內存不足的異常。


JVM優化參數

1. 與串行回收器相關的參數

-XX:+UseSerialGC:在新生代和老年代使用串行回收器。

-XX:+SuivivorRatio:設置 eden 區大小和 survivor 區大小的比例。

-XX:+PretenureSizeThreshold:設置大對象直接進入老年代的閾值。當對象的大小超過這個值時,將直接在老年代分配。

-XX:MaxTenuringThreshold:設置對象進入老年代的年齡的最大值。每一次 Minor GC 後,對象年齡就加 1。任何大於這個年齡的對象,一定會進入老年代。

2. 與並行 GC 相關的參數

-XX:+UseParNewGC: 在新生代使用並行收集器。

-XX:+UseParallelOldGC: 老年代使用並行回收收集器。

-XX:ParallelGCThreads:設置用於垃圾回收的線程數。通常情況下可以和 CPU 數量相等。但在 CPU 數量比較多的情況下,設置相對較小的數值也是合理的。

-XX:MaxGCPauseMills:設置最大垃圾收集停頓時間。它的值是一個大於 0 的整數。收集器在工作時,會調整 Java 堆大小或者其他一些參數,儘可能地把停頓時間控制在 MaxGCPauseMills 以內。

-XX:GCTimeRatio:設置吞吐量大小,它的值是一個 0-100 之間的整數。假設 GCTimeRatio 的值為 n,那麼系統將花費不超過 1/(1+n) 的時間用於垃圾收集。

-XX:+UseAdaptiveSizePolicy:打開自適應 GC 策略。在這種模式下,新生代的大小,eden 和 survivor 的比例、晉升老年代的對象年齡等參數會被自動調整,以達到在堆大小、吞吐量和停頓時間之間的平衡點。

3. 與 CMS 回收器相關的參數

-XX:+UseConcMarkSweepGC: 新生代使用並行收集器,老年代使用 CMS+串行收集器。

-XX:+ParallelCMSThreads: 設定 CMS 的線程數量。

-XX:+CMSInitiatingOccupancyFraction:設置 CMS 收集器在老年代空間被使用多少後觸發,默認為 68%。

-XX:+UseFullGCsBeforeCompaction:設定進行多少次 CMS 垃圾回收後,進行一次內存壓縮。

-XX:+CMSClassUnloadingEnabled:允許對類元數據進行回收。

-XX:+CMSParallelRemarkEndable:啟用並行重標記。

-XX:CMSInitatingPermOccupancyFraction:當永久區佔用率達到這一百分比後,啟動 CMS 回收 (前提是-XX:+CMSClassUnloadingEnabled 激活了)。

-XX:UseCMSInitatingOccupancyOnly:表示只在到達閾值的時候,才進行 CMS 回收。

-XX:+CMSIncrementalMode:使用增量模式,比較適合單 CPU。

4. 與 G1 回收器相關的參數

-XX:+UseG1GC:使用 G1 回收器。

-XX:+UnlockExperimentalVMOptions:允許使用實驗性參數。

-XX:+MaxGCPauseMills:設置最大垃圾收集停頓時間。

-XX:+GCPauseIntervalMills:設置停頓間隔時間。

5. 其他參數

-XX:+DisableExplicitGC: 禁用顯示 GC。

常用參數如下

"

概述

JAVA提供了垃圾回收器(garbage collector)來自動檢測對象的作用域),可自動把不再被使用的存儲空間釋放掉,也就是說,GC機制可以有效地防止內存洩露以及內存溢出。


GC任務

JAVA 垃圾回收器的主要任務是:

  • 分配內存
  • 確保被引用對象的內存不被錯誤地回收
  • 回收不再被引用的對象的內存空間

凡事都有兩面性。垃圾回收器在把程序員從釋放內存的複雜工作中解放出來的同時,為了實現垃圾回收,garbage collector必須跟蹤內存的使用情況,釋放沒用的對象,在完成內存的釋放之後還需要處理堆中的碎片, 這樣做必定會增加JVM的負擔。


JAVA 內存區域

先看看JAVA程序在執行的時候,內存究竟是如何劃分的。

詳解JAVA的GC機制與JVM優化參數總結

私有內存區的區域名稱和相應的特性如下表所示:

詳解JAVA的GC機制與JVM優化參數總結

這裡主要說一下虛擬機棧中的局部變量表,裡面存放了三個信息:

  • 各種基本數據類型(boolean、byte、char、short、int、float、long、double)
  • 對象引用(reference)
  • returnAddress地址

這個returnAddress和程序計數器有什麼區別?前者是指示JVM的指令執行到哪一行,後者則是代碼執行到哪一行。

私有內存區伴隨著線程的產生而產生,一旦線程中止,私有內存區也會自動消除。

詳解JAVA的GC機制與JVM優化參數總結


JAVA堆

堆內存是由存活和死亡的對象組成的。存活的對象是應用可以訪問的,不會被垃圾回收。死亡的對象是應用不可訪問尚且還沒有被垃圾收集器回收掉的對象。一直到垃圾收集器把這些對象回收掉之前,他們會一直佔據堆內存空間。

堆是應用程序在運行期請求操作系統分配給自己的向高地址擴展的數據結構,是不連續的內存區域。用一句話總結堆的作用:程序運行時動態申請某個大小的內存空間

詳解JAVA的GC機制與JVM優化參數總結

新生代:剛剛新建的對象在Eden中,經歷一次Minor GC,Eden中的存活對象就會被移動到第一塊survivor space S0,Eden被清空;等Eden區再滿了,就再觸發一次Minor GC,Eden和S0中的存活對象又會被複制送入第二塊survivor space S1。S0和Eden被清空,然後下一輪S0與S1交換角色,如此循環往復。如果對象的複製次數達到16次,該對象就會被送到老年代中。

老年代:如果某個對象經歷了幾次垃圾回收之後還存活,就會被存放到老年代中。老年代的空間一般比新生代大。

詳解JAVA的GC機制與JVM優化參數總結

不過實際運行中,Major GC會伴隨至少一次 Minor GC,因此也不必過多糾結於到底是哪種GC(在有些資料中看到把full GC和Minor GC等價的說法)。

那麼,當我們創建一個對象後,它會被放在堆內存的哪個部分呢?

詳解JAVA的GC機制與JVM優化參數總結

如果Major GC之後還是老年代不足,那JVM就會拋出內存不足的異常。


JVM優化參數

1. 與串行回收器相關的參數

-XX:+UseSerialGC:在新生代和老年代使用串行回收器。

-XX:+SuivivorRatio:設置 eden 區大小和 survivor 區大小的比例。

-XX:+PretenureSizeThreshold:設置大對象直接進入老年代的閾值。當對象的大小超過這個值時,將直接在老年代分配。

-XX:MaxTenuringThreshold:設置對象進入老年代的年齡的最大值。每一次 Minor GC 後,對象年齡就加 1。任何大於這個年齡的對象,一定會進入老年代。

2. 與並行 GC 相關的參數

-XX:+UseParNewGC: 在新生代使用並行收集器。

-XX:+UseParallelOldGC: 老年代使用並行回收收集器。

-XX:ParallelGCThreads:設置用於垃圾回收的線程數。通常情況下可以和 CPU 數量相等。但在 CPU 數量比較多的情況下,設置相對較小的數值也是合理的。

-XX:MaxGCPauseMills:設置最大垃圾收集停頓時間。它的值是一個大於 0 的整數。收集器在工作時,會調整 Java 堆大小或者其他一些參數,儘可能地把停頓時間控制在 MaxGCPauseMills 以內。

-XX:GCTimeRatio:設置吞吐量大小,它的值是一個 0-100 之間的整數。假設 GCTimeRatio 的值為 n,那麼系統將花費不超過 1/(1+n) 的時間用於垃圾收集。

-XX:+UseAdaptiveSizePolicy:打開自適應 GC 策略。在這種模式下,新生代的大小,eden 和 survivor 的比例、晉升老年代的對象年齡等參數會被自動調整,以達到在堆大小、吞吐量和停頓時間之間的平衡點。

3. 與 CMS 回收器相關的參數

-XX:+UseConcMarkSweepGC: 新生代使用並行收集器,老年代使用 CMS+串行收集器。

-XX:+ParallelCMSThreads: 設定 CMS 的線程數量。

-XX:+CMSInitiatingOccupancyFraction:設置 CMS 收集器在老年代空間被使用多少後觸發,默認為 68%。

-XX:+UseFullGCsBeforeCompaction:設定進行多少次 CMS 垃圾回收後,進行一次內存壓縮。

-XX:+CMSClassUnloadingEnabled:允許對類元數據進行回收。

-XX:+CMSParallelRemarkEndable:啟用並行重標記。

-XX:CMSInitatingPermOccupancyFraction:當永久區佔用率達到這一百分比後,啟動 CMS 回收 (前提是-XX:+CMSClassUnloadingEnabled 激活了)。

-XX:UseCMSInitatingOccupancyOnly:表示只在到達閾值的時候,才進行 CMS 回收。

-XX:+CMSIncrementalMode:使用增量模式,比較適合單 CPU。

4. 與 G1 回收器相關的參數

-XX:+UseG1GC:使用 G1 回收器。

-XX:+UnlockExperimentalVMOptions:允許使用實驗性參數。

-XX:+MaxGCPauseMills:設置最大垃圾收集停頓時間。

-XX:+GCPauseIntervalMills:設置停頓間隔時間。

5. 其他參數

-XX:+DisableExplicitGC: 禁用顯示 GC。

常用參數如下

詳解JAVA的GC機制與JVM優化參數總結


後面會分享更多devops和DBA方面的內容,感興趣的朋友可以關注一下~

"

概述

JAVA提供了垃圾回收器(garbage collector)來自動檢測對象的作用域),可自動把不再被使用的存儲空間釋放掉,也就是說,GC機制可以有效地防止內存洩露以及內存溢出。


GC任務

JAVA 垃圾回收器的主要任務是:

  • 分配內存
  • 確保被引用對象的內存不被錯誤地回收
  • 回收不再被引用的對象的內存空間

凡事都有兩面性。垃圾回收器在把程序員從釋放內存的複雜工作中解放出來的同時,為了實現垃圾回收,garbage collector必須跟蹤內存的使用情況,釋放沒用的對象,在完成內存的釋放之後還需要處理堆中的碎片, 這樣做必定會增加JVM的負擔。


JAVA 內存區域

先看看JAVA程序在執行的時候,內存究竟是如何劃分的。

詳解JAVA的GC機制與JVM優化參數總結

私有內存區的區域名稱和相應的特性如下表所示:

詳解JAVA的GC機制與JVM優化參數總結

這裡主要說一下虛擬機棧中的局部變量表,裡面存放了三個信息:

  • 各種基本數據類型(boolean、byte、char、short、int、float、long、double)
  • 對象引用(reference)
  • returnAddress地址

這個returnAddress和程序計數器有什麼區別?前者是指示JVM的指令執行到哪一行,後者則是代碼執行到哪一行。

私有內存區伴隨著線程的產生而產生,一旦線程中止,私有內存區也會自動消除。

詳解JAVA的GC機制與JVM優化參數總結


JAVA堆

堆內存是由存活和死亡的對象組成的。存活的對象是應用可以訪問的,不會被垃圾回收。死亡的對象是應用不可訪問尚且還沒有被垃圾收集器回收掉的對象。一直到垃圾收集器把這些對象回收掉之前,他們會一直佔據堆內存空間。

堆是應用程序在運行期請求操作系統分配給自己的向高地址擴展的數據結構,是不連續的內存區域。用一句話總結堆的作用:程序運行時動態申請某個大小的內存空間

詳解JAVA的GC機制與JVM優化參數總結

新生代:剛剛新建的對象在Eden中,經歷一次Minor GC,Eden中的存活對象就會被移動到第一塊survivor space S0,Eden被清空;等Eden區再滿了,就再觸發一次Minor GC,Eden和S0中的存活對象又會被複制送入第二塊survivor space S1。S0和Eden被清空,然後下一輪S0與S1交換角色,如此循環往復。如果對象的複製次數達到16次,該對象就會被送到老年代中。

老年代:如果某個對象經歷了幾次垃圾回收之後還存活,就會被存放到老年代中。老年代的空間一般比新生代大。

詳解JAVA的GC機制與JVM優化參數總結

不過實際運行中,Major GC會伴隨至少一次 Minor GC,因此也不必過多糾結於到底是哪種GC(在有些資料中看到把full GC和Minor GC等價的說法)。

那麼,當我們創建一個對象後,它會被放在堆內存的哪個部分呢?

詳解JAVA的GC機制與JVM優化參數總結

如果Major GC之後還是老年代不足,那JVM就會拋出內存不足的異常。


JVM優化參數

1. 與串行回收器相關的參數

-XX:+UseSerialGC:在新生代和老年代使用串行回收器。

-XX:+SuivivorRatio:設置 eden 區大小和 survivor 區大小的比例。

-XX:+PretenureSizeThreshold:設置大對象直接進入老年代的閾值。當對象的大小超過這個值時,將直接在老年代分配。

-XX:MaxTenuringThreshold:設置對象進入老年代的年齡的最大值。每一次 Minor GC 後,對象年齡就加 1。任何大於這個年齡的對象,一定會進入老年代。

2. 與並行 GC 相關的參數

-XX:+UseParNewGC: 在新生代使用並行收集器。

-XX:+UseParallelOldGC: 老年代使用並行回收收集器。

-XX:ParallelGCThreads:設置用於垃圾回收的線程數。通常情況下可以和 CPU 數量相等。但在 CPU 數量比較多的情況下,設置相對較小的數值也是合理的。

-XX:MaxGCPauseMills:設置最大垃圾收集停頓時間。它的值是一個大於 0 的整數。收集器在工作時,會調整 Java 堆大小或者其他一些參數,儘可能地把停頓時間控制在 MaxGCPauseMills 以內。

-XX:GCTimeRatio:設置吞吐量大小,它的值是一個 0-100 之間的整數。假設 GCTimeRatio 的值為 n,那麼系統將花費不超過 1/(1+n) 的時間用於垃圾收集。

-XX:+UseAdaptiveSizePolicy:打開自適應 GC 策略。在這種模式下,新生代的大小,eden 和 survivor 的比例、晉升老年代的對象年齡等參數會被自動調整,以達到在堆大小、吞吐量和停頓時間之間的平衡點。

3. 與 CMS 回收器相關的參數

-XX:+UseConcMarkSweepGC: 新生代使用並行收集器,老年代使用 CMS+串行收集器。

-XX:+ParallelCMSThreads: 設定 CMS 的線程數量。

-XX:+CMSInitiatingOccupancyFraction:設置 CMS 收集器在老年代空間被使用多少後觸發,默認為 68%。

-XX:+UseFullGCsBeforeCompaction:設定進行多少次 CMS 垃圾回收後,進行一次內存壓縮。

-XX:+CMSClassUnloadingEnabled:允許對類元數據進行回收。

-XX:+CMSParallelRemarkEndable:啟用並行重標記。

-XX:CMSInitatingPermOccupancyFraction:當永久區佔用率達到這一百分比後,啟動 CMS 回收 (前提是-XX:+CMSClassUnloadingEnabled 激活了)。

-XX:UseCMSInitatingOccupancyOnly:表示只在到達閾值的時候,才進行 CMS 回收。

-XX:+CMSIncrementalMode:使用增量模式,比較適合單 CPU。

4. 與 G1 回收器相關的參數

-XX:+UseG1GC:使用 G1 回收器。

-XX:+UnlockExperimentalVMOptions:允許使用實驗性參數。

-XX:+MaxGCPauseMills:設置最大垃圾收集停頓時間。

-XX:+GCPauseIntervalMills:設置停頓間隔時間。

5. 其他參數

-XX:+DisableExplicitGC: 禁用顯示 GC。

常用參數如下

詳解JAVA的GC機制與JVM優化參數總結


後面會分享更多devops和DBA方面的內容,感興趣的朋友可以關注一下~

詳解JAVA的GC機制與JVM優化參數總結

"

相關推薦

推薦中...