1. 程式人生 > >垃圾回收機制(GC)原理以及jvm調優知識

垃圾回收機制(GC)原理以及jvm調優知識

垃圾回收機制

1. 記憶體的組成:堆(Heap)和非堆(Non-heap)記憶體。

是執行時資料區域,是由new分配的記憶體,因為不知道大小的,應該有程式自己來申請記憶體空間,所以由堆來分配是留給開發人員使用的;

非堆就是JVM留給自己用的。

2. JVM初始分配的記憶體由-Xms指定,預設是實體記憶體的1/64JVM最大分配的記憶體由-Xmx指 定,預設是實體記憶體的1/4預設空餘堆記憶體小於40%時,JVM就會增大堆直到-Xmx的最大限制;空餘堆記憶體大於70%時,JVM會減少堆直到-Xms的最小限制。因此伺服器一般設定-Xms-Xmx相等以避免在每次GC後調整堆的大小。(這個在後邊jvm

調優會用到)。

3. 看張圖片:堆記憶體分配(跟後邊說到的GC原理還有jvm調優引數相關聯




4. 非堆記憶體分配

JVM使用-XX:PermSize設定非堆記憶體初始值,預設是實體記憶體的1/64;由XX:MaxPermSize設定最大非堆記憶體的大小,預設是實體記憶體的1/4

 

上邊名詞的定義和解釋,其實跟接下來要說的垃圾回收機制採用的方法相關:

JVM裡的GC(Garbage Collection)的演算法有很多種,這裡就說最常用的一種,分代收集演算法。

5. 分代收集演算法將記憶體分為幾個區域,將不同生命週期的物件放在不同區域裡:young generationtenured generation

permanet generation。絕大部分的object被分配在young generation(生命週期短),並且大部分的object在這裡die。當young generation滿了之後,將引發minor collection(YGC)。在minor collection後存活的object會被移動到tenured generation(生命週期比較長)。最後,tenured generation滿之後觸發major collectionmajor collectionFull gc會觸發整個heap的回收,包括回收young generationpermanet generation
區域比較穩定,主要存放classloader資訊。

6. young generationeden2survivor區域組成。其中一個survivor區域一直是空的,是eden區域和另一個survivor區域在下一次copy collection後(YGC)活著的object的目的地。objectsurvivo區域被複制直到轉移到tenured區。

7. 我們要儘量減少 Full gc的次數(tenured generation一般比較大,收集的時間較長,頻繁的Full gc會導致應用的效能收到嚴重的影響)

8. 堆記憶體GCJVM(採用分代回收的策略),用較高的頻率對年輕的物件(young generation)進行YGC,而對老物件(tenured generation)較少(tenured generation 滿了後才進行)進行Full GC。這樣就不需要每次GC都將記憶體中所有物件都檢查一遍。

9. 非堆記憶體不GCGC不會在主程式執行期對PermGen Space進行清理,所以如果你的應用中有很多CLASS(特別是動態生成類,當然permgen space存放的內容不僅限於類)的話,就很可能出現PermGen Space錯誤。

至此:GC的執行流程基本就說完了。接下來,看一些jvm的配置引數,通過配置可以防止GC後出現卡頓的現象。

10. 再說一個專案中的問題:

promotion failed垃圾回收時promotion failed是個很頭痛的問題,一般可能是兩種原因產生,第一個原因是救助空間不夠,救助空間裡的物件還不應該被移動到年老代,但年輕代又有很多物件需要放入救助空間;第二個原因是年老代沒有足夠的空間接納來自年輕代的物件;這兩種情況都會轉向Full GC,網站停頓時間較長。

再換一種說法:promontion faild產生的原因是EDEN空間不足的情況下將EDENFrom survivor中的存活物件存入To survivor區時,To survivor區的空間不足,再次晉升到old gen區,而old gen區記憶體也不夠的情況下產生了promontion faild從而導致full gc.那可以推斷出:eden+from survivor < old gen區剩餘記憶體時,不會出現promontion faild的情況。即如下公式:

(Xmx-Xmn)*(1-CMSInitiatingOccupancyFraction/100)>=(Xmn-Xmn/(SurvivorRatior+2))這個不難理解。

進而推斷出:
CMSInitiatingOccupancyFraction <=((Xmx-Xmn)-(Xmn-Xmn/(SurvivorRatior+2)))/(Xmx-Xmn)*100

CMSInitiatingOccupancyFraction低於80%需要調整xmnSurvivorRatior值。

11.網上推薦的jvm配置的最優方案(僅供參考)

-Xmx256M//最大堆大小

-Xms256M //初始堆大小

-Xmn96M //年輕代大小Sun官方推薦配置為整個堆的3/8

-XX:PermSize=500M //設定持久代(perm gen)初始值 非堆記憶體

-XX:MaxPermSize=500M //設定持久代最大值 --------XMXXMS設定一樣大,MaxPermSizeMinPermSize設定一樣大,這樣可以減輕伸縮堆大小帶來的壓力。

-Xss256K //每個執行緒的堆疊大小

-XX:+DisableExplicitGC //關閉System.gc(),免得程式設計師誤呼叫gc方法影響效能

-XX:SurvivorRatio=1 //Eden區與Survivor區的大小比值(計算公式)

-XX:+UseConcMarkSweepGC //使用CMS記憶體收集(使用CMS的好處是用盡量少的新生代,經驗值是128M256M, 然後老生代利用CMS並行收集, 這樣能保證系統低延遲的吞吐效率。 實際上cms的收集停頓時間非常的短,2G的記憶體, 大約2080ms的應用程式停頓時間)

-XX:+UseParNewGC //設定年輕代為並行收集(使用CMS的好處是用盡量少的新生代,經驗值是128M256M, 然後老生代利用CMS並行收集, 這樣能保證系統低延遲的吞吐效率。 實際上cms的收集停頓時間非常的短,2G的記憶體, 大約2080ms的應用程式停頓時間)。

-XX:+CMSParallelRemarkEnabled // 降低標記停頓

-XX:+UseCMSCompactAtFullCollection //FULL GC的時候,對年老代的壓縮 消除碎片1

-XX:CMSFullGCsBeforeCompaction=0 // 多少次後進行記憶體壓縮2

-XX:+CMSClassUnloadingEnabled

-XX:LargePageSizeInBytes=128M //記憶體頁的大小不可設定過大, 會影響Perm的大小

-XX:+UseFastAccessorMethods //原始型別的快速優化

-XX:+UseCMSInitiatingOccupancyOnly //使用手動定義初始化定義開始CMS收集,禁止hostspot自行觸發CMS GC

-XX:CMSInitiatingOccupancyFraction=80 //使用cms作為垃圾回收 使用80%後開始CMS收集

-XX:SoftRefLRUPolicyMSPerMB=0 //每兆堆空閒空間中SoftReference的存活時間

-XX:+PrintClassHistogram

-XX:+PrintGCDetails

-XX:+PrintGCTimeStamps

-XX:+PrintHeapAtGC //列印GC前後的詳細堆疊資訊

相關推薦

垃圾回收機制GC原理以及jvm調知識

垃圾回收機制 1. 記憶體的組成:堆(Heap)和非堆(Non-heap)記憶體。 堆是執行時資料區域,是由new分配的記憶體,因為不知道大小的,應該有程式自己來申請記憶體空間,所以由堆來分配是留給開

垃圾回收機制GC Java記憶體區域及物件

前言   上一篇文章Java記憶體區域及物件講述了Java記憶體執行時的各個部分,其中程式計數器、虛擬機器棧、本地方法棧3個區域隨執行緒生而生,隨執行緒滅而滅,在這幾個區域是不需要過多的考慮回收的問題的,因為方法結束或者執行緒結束時,記憶體自然就跟隨著回收了;而Java堆和方法區則不一樣,一個介面中的多個實

HotSpot的演算法實現 垃圾回收機制GC

上一篇文章垃圾回收機制(GC)從理論上介紹了物件存活判定演算法和垃圾收集演算法,而在HotSpot虛擬機器上實現這些演算法時,必須對演算法的執行效率有嚴格的考量,才能保證虛擬機器高效執行。 列舉根節點   以可達性分析中從GC Roots 節點找引用鏈這個操作為例,可作為GC 

Java垃圾回收機制GC

什麼是垃圾(堆): 1、沒有被引用的物件就是垃圾物件 2、所有不再存活的物件 3、沒有物件引用指向原先分配給某個物件的記憶體時(百度百科) Java棧空間垃圾回收: 1、我們定義一些基本型別的變數和對應的變數資料還有物件的引用變數,都在函式的棧記憶體中分配。當在一段程式碼塊定義一

python垃圾回收機制GC

計數 gc算法 ont 結構 減少 檢測 告訴 釋放 列表 Python垃圾回收(GC)三層心法,你了解到第幾層? 垃圾回收機制應該是面試最常問的問題了,那麽Python中的垃圾回收機制(Garbage Collection)是怎麽解決的呢?我記得每一本python入

.NET垃圾回收機制

sel 結點 是個 pac public 良好的 方案 環境 哪裏 一、GC的必要性   1、應用程序對資源操作,通常簡單分為以下幾個步驟:為對應的資源分配內存 → 初始化內存 → 使用資源 → 清理資源 → 釋放內存。   2、應用程序對資源(內存使用)管理的方式,常見的

成為JavaGC專家3—如何監控Java垃圾回收機制轉載

生成 head builder 清除 內存清理 每次 com con book 原文:http://www.importnew.com/3146.html 為什麽需要優化GC 或者說的更確切一些,對於基於Java的服務,是否有必要優化GC?應該說,對於所有的基於Java的服

Java垃圾回收機制3

(一) 關於垃圾回收的幾點補充   經過上述的說明,可以發現垃圾回收有以下的幾個特點:   (1)垃圾收集發生的不可預知性:由於實現了不同的垃圾回收演算法和採用了不同的收集機制,所以它有可能是定時發生,有可能是當出現系統空閒CPU資源時發生,也有可能是和原始的垃圾收集一樣,等

JVM垃圾回收機制

一、什麼是垃圾? 1:引用計數演算法:給物件中加一個引用計數器,每當有一個引用指向它時,計數器的值就加一,引用失效時,計數器的值就減一。當該物件引用計數器等於0的時候就被視為垃圾。 該演算法存在很大的缺陷,若兩個物件存在互相引用,則兩者的引用計數器都

Java 垃圾回收機制以及怎麼減少呼叫GC,提高效能

 綜合了若干人的blog~ 1. 垃圾回收的意義  在C++中,物件所佔的記憶體在程式結束執行之前一直被佔用,在明確釋放之前不能分配給其它物件;而在Java中,當沒有物件引用指向原先分配給某個物件的記憶體時,該記憶體便成為垃圾。JVM的一個系統級執行緒會自動釋放該記憶體

php垃圾回收機制PHP新的垃圾回收機制:Zend GC詳解

概述     在5.2及更早版本的PHP中,沒有專門的垃圾回收器GC(Garbage Collection),引擎在判斷一個變數空間是否能夠被釋放的時候是依據這個變數的zval的refcount的值,如果refcount為0,那麼變數的空間可以被釋放,否則就不釋放,這是一種

java垃圾回收機制摘自瘋狂JAVA講義以及一位博主的分享

java語言不需要程式設計師直接控制記憶體回收。Java的記憶體分配和回收都是由jre在後臺自動進行。jre會負責回收那些不在使用的記憶體。這種機制被稱為垃圾回收。(Garbage Collection GC)。 通常jre會提供一個後臺執行緒來進行監測和控制,一般都市在cpu空閒或記憶體不足時自動

Java 垃圾回收機制早期版本

重新 速度 交互 綜合 技術 -1 遍歷 我們 後臺 Java 垃圾回收機制在我們普通理解來看,應該視為一種低優先級的後臺進程來實現的,其實早期版本的Java虛擬機並非以這種方式實現的。 先從一種很簡單的垃圾回收方式開始。 引用計數   引用計數是一種簡單但是速度很慢

JVM 垃圾回收機制GC效能調

一、GC概要: JVM堆相關知識     為什麼先說JVM堆?     JVM的堆是Java物件的活動空間,程式中的類的物件從中分配空間,其儲存著正在執行著的應用程式用到的所有物件。這些物件的建立方式就是那些new一類的操作,當物件

深入理解JVM——配置引數垃圾回收演算法

深入理解JVM(三)——配置引數 1、跟蹤引數 2、堆分配引數 3、棧分配引數 這三類引數分別用於跟蹤監控JVM狀態,分配堆記憶體、棧記憶體。 跟蹤引數 跟蹤監控JVM,用於JVM調優以及故障排查。 1、當發生GC時,列印GC簡要資訊 使

深入理解JVM——垃圾回收

深入理解JVM(五)——垃圾回收器 JVM的垃圾回收主要是針對以上堆空間的垃圾回收,當然其實也會針對元資料區(永久區)進行垃圾回收。 序列收集器 使用單執行緒進行垃圾回收。 對新生代回收使用複製演算法, 對老年代使用標記壓縮演算法, 最古老最穩定

垃圾回收策略

垃圾回收: 即收集已經“死去”的物件。Java記憶體執行時資料區中程式計數器、虛擬機器棧、本地方法棧三個部分的隨執行緒而生,隨執行緒而滅。每個棧幀中分配多少記憶體在類結構確定時就是可知的,因此這三個區域的記憶體分配和回收都具備確定性,不需過多考慮回收問題,因為方法結束或執行

Java垃圾回收機制GC

        說到垃圾回收(Garbage Collection,GC),很多人就會自然而然地把它和Java聯絡起來。在Java中,程式設計師不需要去關心記憶體動態分配和垃圾回收的問題,這一切都交給了JVM來處理。顧名思義,垃圾回收就是釋放垃圾佔用的空間一、如何確定某個物件

Python之美[從菜鳥到高手]--Python垃圾回收機制gc模組詳解

    Python中的垃圾回收是以引用計數為主,標記-清除和分代收集為輔。引用計數最大缺陷就是迴圈引用的問題,所以Python採用了輔助方法。本篇文章並不詳細探討Python的垃圾回收機制的內部實現,而是以gc模組為切入點學習Python的垃圾回收機制,如果想深入可以讀讀

UI效能優化Overdraw排查和調

文章目錄 概述與案例 排查技巧一:檢視是否過度繪製 排查技巧二:通過Hierachy View或者Layout Inspecot檢視佈局層級 Overdraw優化策略-扁平化 一、至尊超薄