1. 程式人生 > >【JVM原理與優化】JVM記憶體設定多大合適?Xmx和Xmn如何設定?

【JVM原理與優化】JVM記憶體設定多大合適?Xmx和Xmn如何設定?

問題:

新上線一個java服務,或者是RPC或者是WEB站點, 記憶體的設定該怎麼設定呢?設定成多大比較合適,既不浪費記憶體,又不影響效能呢?

分析:

依據的原則是根據Java Performance裡面的推薦公式來進行設定。

WX20171103-112002.png

具體來講:

Java整個堆大小設定,Xmx 和 Xms設定為老年代存活物件的3-4倍,即FullGC之後的老年代記憶體佔用的3-4倍

永久代 PermSize和MaxPermSize設定為老年代存活物件的1.2-1.5倍。

年輕代Xmn的設定為老年代存活物件的1-1.5倍。

老年代的記憶體大小設定為老年代存活物件的2-3倍。

BTW:

     1、Sun官方建議年輕代的大小為整個堆的3/8左右, 所以按照上述設定的方式,基本符合Sun的建議。 

     2、堆大小=年輕代大小+年老代大小, 即xmx=xmn+老年代大小 。 Permsize不影響堆大小。

     3、為什麼要按照上面的來進行設定呢? 沒有具體的說明,但應該是根據多種調優之後得出的一個結論。

如何確認老年代存活物件大小?

方式1(推薦/比較穩妥):

     JVM引數中新增GC日誌,GC日誌中會記錄每次FullGC之後各代的記憶體大小,觀察老年代GC之後的空間大小。可觀察一段時間內(比如2天)的FullGC之後的記憶體情況,根據多次的FullGC之後的老年代的空間大小資料來預估FullGC之後老年代的存活物件大小(可根據多次FullGC之後的記憶體大小取平均值)

方式2:(強制觸發FullGC, 會影響線上服務,慎用)

     方式1的方式比較可行,但需要更改JVM引數,並分析日誌。同時,在使用CMS回收器的時候,有可能不能觸發FullGC(只發生CMS GC),所以日誌中並沒有記錄FullGC的日誌。在分析的時候就比較難處理。

     BTW:使用jstat -gcutil工具來看FullGC的時候, CMS GC是會造成2次的FullGC次數增加。 具體可參見之前寫的一篇關於jstat使用的文章

     所以,有時候需要強制觸發一次FullGC,來觀察FullGC之後的老年代存活物件大小。

     注:強制觸發FullGC,會造成線上服務停頓(STW),要謹慎,建議的操作方式為,在強制FullGC前先把服務節點摘除,FullGC之後再將服務掛回可用節點,對外提供服務

     在不同時間段觸發FullGC,根據多次FullGC之後的老年代記憶體情況來預估FullGC之後的老年代存活物件大小

如何觸發FullGC ?

               使用jmap工具可觸發FullGC 

               jmap -dump:live,format=b,file=heap.bin <pid> 將當前的存活物件dump到檔案,此時會觸發FullGC

               jmap -histo:live <pid> 列印每個class的例項數目,記憶體佔用,類全名資訊.live子引數加上後,只統計活的物件數量. 此時會觸發FullGC

具體操作例項:

以我司的一個RPC服務為例。

BTW:剛上線的新服務,不知道該設定多大的記憶體的時候,可以先多設定一點記憶體,然後根據GC之後的情況來進行分析。

初始JVM記憶體引數設定為: Xmx=2G Xms=2G xmn=1G 

使用jstat 檢視當前的GC情況。如下圖:

WX20171103-112025.png

YGC平均耗時: 173.825s/15799=11ms

FGC平均耗時:0.817s/41=19.9ms

平均大約10-20s會產生一次YGC

看起來似乎不錯,YGC觸發的頻率不高,FGC的耗時也不高,但這樣的記憶體設定是不是有些浪費呢?

為了快速看資料,我們使用了方式2,產生了幾次FullGC,FullGC之後,使用的jmap -heap 來看的當前的堆記憶體情況(也可以根據GC日誌來看)

heap情況如下圖:(命令 : jmap -heap <pid>)

WX20171103-112039.png

上圖中的concurrent mark-sweep generation即為老年代的記憶體描述。

老年代的記憶體佔用為100M左右。 按照整個堆大小是老年代(FullGC)之後的3-4倍計算的話,設定各代的記憶體情況如下:

     Xmx=512m  Xms=512m  Xmn=128m PermSize=128m  老年代的大小為 (512-128=384m)為老年代存活物件大小的3倍左右

調整之後的,heap情況

WX20171103-112102.png

GC情況如下:

WX20171103-112111.png

YGC 差不多在10s左右觸發一次。每次YGC平均耗時大約9.41ms。可接受。

FGC平均耗時:0.016s/2=8ms

整體的GC耗時減少。但GC頻率比之前的2G時的要多了一些。

注: 看上述GC的時候,發現YGC的次數突然會增多很多個,比如 從1359次到了1364次。具體原因是?

總結:

在記憶體相對緊張的情況下,可以按照上述的方式來進行記憶體的調優, 找到一個在GC頻率和GC耗時上都可接受的一個記憶體設定,可以用較小的記憶體滿足當前的服務需要

但當記憶體相對寬裕的時候,可以相對給服務多增加一點記憶體,可以減少GC的頻率,GC的耗時相應會增加一些。 一般要求低延時的可以考慮多設定一點記憶體, 對延時要求不高的,可以按照上述方式設定較小記憶體。 

補充:

永久代(方法區)並不在堆內,所以之前有看過一篇文章中描述的 整個堆大小=年輕代+年老代+永久代的描述是不正確的。 

問題:

1、GC頻率和GC時間多少合適?

2、YGC何時觸發,FGC何時觸發?

3、記憶體設定越大,GC的耗時是否就會越長?為什麼? 

相關推薦

JVM原理優化JVM記憶體設定合適XmxXmn如何設定

問題: 新上線一個java服務,或者是RPC或者是WEB站點, 記憶體的設定該怎麼設定呢?設定成多大比較合適,既不浪費記憶體,又不影響效能呢? 分析: 依據的原則是根據Java Performance裡面的推薦公式來進行設定。 具體來講: Java整

JVM記憶體設定合適XmxXmn如何設定

問題: 新上線一個java服務,或者是RPC或者是WEB站點, 記憶體的設定該怎麼設定呢?設定成多大比較合適,既不浪費記憶體,又不影響效能呢? 分析: 依據的原則是根據Java Performance裡面的推薦公式來進行設定。 具體來講: Java整個堆

資料結構演算法內部排序之四:歸併排序快速排序(含完整原始碼)

前言      之所以把歸併排序和快速排序放在一起探討,很明顯兩者有一些相似之處:這兩種排序演算法都採用了分治的思想。下面來逐個分析其實現思想。歸併排序實現思想       歸併的含義很明顯就是將兩個或者兩個以上的有序表組合成一個新的有序表。歸併排序中一般所用到的是2-路歸併

網紅代運營網紅有的商業價值?

沒人否認網紅的商業價值,也沒人敢“認證”網紅的投資價值。從投資邏輯來看,個人網紅是不被資本市場看好的。理性的投資人最怕的是人的不可控,他本應該相信資料和模型。畢竟網紅能紅多久是很難預測的,要不然羅振宇也不會著急,要將Papi醬一次性收割, “落袋為安”。哄擡“網紅”泡沫的主謀,最終也會是戳破泡沫的劊子手。

基礎+實戰JVM原理優化系列之八:如何檢視JVM引數配置?

1. 檢視JAVA版本資訊 2. 檢視JVM執行模式  在$JAVA_HOME/jre/bin下有client和server兩個目錄,分別代表JVM的兩種執行模式。   client執行模式,針對桌面應用,載入速度比server模式快10%,而執行速度為server模

JVM原理優化之二:記憶體管理

1. 記憶體分配策略: 1. 物件優先在Eden分配 2. 大物件直接進入老年代 3. 長期存活物件將進入老年代(當它的年齡增加到一定程度 (預設為15歲 ),就會被晉升到老年代中 。物件晉升老年代的年齡閾值,可以通過引數 -XX:MaxTenuringThreshold來

3.深入jvm核心-原理、診斷優化-10. jvm位元組碼執行

一、位元組碼 javap 簡單的位元組碼執行過程 常用的位元組碼 使用ASM生成Java位元組碼 JIT及其相關引數 jav

淺度渣文JVM——G1收集器

原文連結:http://www.dubby.cn/detail.html?id=9059 1. 概述 硬體和軟體要求 作業系統要求Windows XP或者更高,Mac OS X和Linux都可以。請注意,這些測試操作是在Windows 7上完成的,尚未在所有平臺上進行測試。 但是,一切都應該在OS

淺度渣文JVM——簡述垃圾回收

原文連結:http://www.dubby.cn/detail.html?id=9062 垃圾回收的簡單描述 什麼是自動垃圾收集? 自動垃圾收集是檢視堆記憶體的過程,可以識別哪些物件正在使用,哪些不是,以及刪除未使用的物件。一個正在使用的物件或一個被引用的物件,意味著你的程式的某個部分仍然保持著一個指向

讀書筆記-從Paxos到ZooKeeper分散式一致性原理實踐 第七章 Zk技術內幕

系統模型 資料模型 ZNode是ZK中資料的最小單元,每個ZNode上都可以儲存資料,同時還可以掛載子節點,形成一個層次化的名稱空間——樹. 樹 Zk中每個資料節點都稱為ZNode,所有ZNode形成樹形結構。 事務ID 事務是指ZK改變

jvm原理優化

jvm的啟動: 裝載配置 => 載入類 => 執行主方法 由類載入器載入類檔案到記憶體,包括堆,棧,方法區以及本地方法區等等,,, 方法區儲存類的資訊(常量池,欄位方法等資訊等等) 堆包含了應用程式中的系統物件 棧是執行緒私有,由一系列棧幀組成,每一次

SSO單點登入實現原理總結

一、什麼是單點登入SSO(Single Sign-On)        SSO是一種統一認證和授權機制,指訪問同一伺服器不同應用中的受保護資源的同一使用者,只需要登入一次,即通過一個應用中的安全驗證後,再訪問其他應用中的受保護資源時,不再需要重新登入驗證。 二、單點登入解決

HEVC學習研究42、HEVC幀內編碼的原理實現(下)

4、編碼幀內預測模式 大量增加可選擇的預測模式可以提供更高的編碼效率,同時要求編碼預測模式有更加高效的方法降低更多模式帶來的負擔。與H.264採用一個最可能模式不同的是,對於亮度分量,三個最可能模式用於預測實際的幀內預測模式。同時,也考慮了三個最可能模式中的冗餘資訊,重複的

JVM原理工作流程

作為一名Java使用者,掌握JVM的體系結構也是必須的。說起Java,人們首先想到的是Java程式語言,然而事實上,Java是一種技術,它由四方面組成:Java程式語言、Java類檔案格式、Java虛擬機器和Java應用程式介面(Java API)。它們的關係如下圖所示:執行

HEVC學習研究39、HEVC幀內編碼的原理實現(上)

【前面N篇博文都講了一些HEVC幀內預測的程式碼結構和簡單的方法,但是尚未對整體的演算法和實現做一個比較完整的描述。本篇藉助參考文獻《High Efficiency Video Coding (HEVC) -- Algorithms and Architectures》的

讀書筆記-從Paxos到ZooKeeper分散式一致性原理實踐第二章 一致性協議

2PC與 3PC 在分散式系統中,每個節點都明確知道自己事務操作的成功或失敗,但無法獲取其他分散式節點的操作結果。因此當一個事務需要跨節點進行事務操作時,需要引入協調者(Coordinator)元件來統一排程所有分散式節點的執行邏輯,這些被排程的節點稱為參與者

Cookie & Session會話管理控制

有效期 unset font 重置 也有 姓名 本地 tro 讀取 用現實生活 類比Cookie 和 Session : 兩個關於開會的故事: 在幾十年前人們開會的時候,都需要帶上一個參會證。這個參會證上有這個人的職務、姓名、單位、照片等信息。在開會的時候,會議安保人員

python當中的坑閉包lambda

沒有 被調用 叠代 oca ref ron 解決 應該 sin 先來看一個栗子: def create(): return [lambda x:i*x for i in range(5)] for i in create(): print(i(2))

設計模式Android抽象工廠模式——嵌合體克隆工廠

設計模式 android 什麽是抽象工廠模式 所謂抽象工廠模式,就是為創建一組相關或者是互相依賴的對象提供一個接口,而不需要指定它們的具體類的設計模式。抽象工廠模式適用於一個對象族有相同的約束的情況,用不抽象的語言解釋就是國內著名開發者服務商環信在Android和iOS平臺都提供了IM SDK,盡管功

設計模式Android工廠方法模式——化工女神的工廠

設計模式 android 什麽是工廠方法模式 所謂工廠方法模式,就是定義一個用於創建對象的接口,讓子類決定實例化哪個類的設計模式。工廠模式適用於需要生成復雜對象的地方。 工廠方法模式的實現方式 這次我不打算用文學作品舉例了,以前前幾篇文章用《三國演義》和《水滸傳》舉例,某IT社區的技術編輯居然認為我是