日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 综合教程 >内容正文

综合教程

JVM内存调优之监控篇

發(fā)布時(shí)間:2024/6/21 综合教程 28 生活家
生活随笔 收集整理的這篇文章主要介紹了 JVM内存调优之监控篇 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

JVM停頓

JVM(Java虛擬機(jī))在運(yùn)行過(guò)程中會(huì)產(chǎn)生很多停頓,常見的有GC、JIT、取消偏向鎖(RevokeBias)、RedefineClasses(AOP)等。對(duì)應(yīng)用程序影響最大的則是GC停頓。RocketMQ盡量避免FullGC,但MinorGC帶來(lái)的停頓是難以避免的。針對(duì)GC調(diào)優(yōu)是一個(gè)很伽利略的問(wèn)題,需要通過(guò)大量的測(cè)試來(lái)幫助應(yīng)用程序調(diào)整GC參數(shù),比如可以通過(guò)調(diào)整堆大小,GC的時(shí)機(jī),優(yōu)化數(shù)據(jù)結(jié)構(gòu)等手段進(jìn)行調(diào)優(yōu)。

對(duì)于其它JVM停頓,可以通過(guò)-XX:+PrintGCApplicationStoppedTime將JVM停頓時(shí)間輸出到GC日志中。通過(guò)-XX:+PrintSafepointStatistics -XX: PrintSafepointStatisticsCount=1輸出具體的停頓原因,并進(jìn)行針對(duì)性的優(yōu)化。比如在RocketMQ中發(fā)現(xiàn)取RevokeBias產(chǎn)生了大量的停頓,通過(guò)-XX:-UseBiasedLocking關(guān)閉了偏向鎖特性。

另外,GC日志的輸出會(huì)發(fā)生文件IO,有時(shí)候也會(huì)造成不必要的停頓,可以將GC日志輸出到tmpfs(內(nèi)存文件系統(tǒng))中,但tmpfs會(huì)消耗內(nèi)存,為了避免內(nèi)存被浪費(fèi)可以使用-XX:+UseGCLogFileRotation滾動(dòng)GC日志。

除了GC日志會(huì)產(chǎn)生文件IO,JVM會(huì)將jstat命令需要的一些統(tǒng)計(jì)數(shù)據(jù)輸出到/tmp(hsperfdata)目錄下,可通過(guò)-XX:+PerfDisableSharedMem關(guān)閉該特性,并使用JMX來(lái)代替jstat。

上文參照:

http://www.cnblogs.com/hujiapeng/p/6235895.html

基本配置

-Xloggc:/dev/shm/gc-myapplication.log -XX:+PrintGCDateStamps -XX:+PrintGCDetails

詳見JVM實(shí)用參數(shù)(八)GC日志,有人擔(dān)心寫GC日志會(huì)影響性能,但測(cè)試下來(lái)實(shí)在沒什么影響,還是留一份用來(lái)排查好。

到后來(lái),又發(fā)現(xiàn)如果遇上高IO的情況,如果GC的時(shí)候,操作系統(tǒng)正在flush pageCache 到磁盤,也可能導(dǎo)致GC log文件被鎖住,從而讓GC結(jié)束不了。所以把它指向了/dev/shm 這種內(nèi)存中文件系統(tǒng),避免這種停頓,詳見Eliminating Large JVM GC Pauses Caused by Background IO Traffic

用+PrintGCDateStamps而不是PrintGCTimeStamps,打印可讀的日期而不是時(shí)間戳。

-XX:+PrintGCApplicationStoppedTime,它的名字沒起好,它除了打印清晰的GC停頓時(shí)間外,還可以打印其他的停頓時(shí)間,比如取消偏向鎖,class 被agent redefine,code deoptimization等等,有助于發(fā)現(xiàn)一些原來(lái)沒想到的問(wèn)題,建議也加上。如果真的發(fā)現(xiàn)了一些不知什么的停頓,再臨時(shí)加上"-XX:+PrintSafepointStatistics -XX: PrintSafepointStatisticsCount=1"找原因。

GC日志默認(rèn)會(huì)在重啟后清空,但有人擔(dān)心長(zhǎng)期運(yùn)行不重啟的應(yīng)用會(huì)把文件弄得很大,有"-XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=1M"的參數(shù)可以讓日志滾動(dòng)起來(lái)。但重啟后的文件名太混亂太讓人頭痛,所以還是不加。

3. 監(jiān)控篇

JVM輸出的各種日志,如果未指定路徑,通常會(huì)生成到運(yùn)行應(yīng)用的相同目錄,為了避免有時(shí)候在不同的地方執(zhí)行啟動(dòng)腳本,一般將日志路徑集中設(shè)到一個(gè)固定的地方。

3.1-XX:+PrintCommandLineFlags

運(yùn)維有時(shí)會(huì)對(duì)啟動(dòng)參數(shù)做一些臨時(shí)的更改,將每次啟動(dòng)的參數(shù)輸出到stdout,將來(lái)有據(jù)可查。
打印出來(lái)的是命令行里設(shè)置了的參數(shù)以及因?yàn)檫@些參數(shù)隱式影響的參數(shù),比如開了CMS后,-XX:+UseParNewGC也被自動(dòng)打開。

3.2 -XX:-OmitStackTraceInFastThrow

為異常設(shè)置StackTrace是個(gè)昂貴的操作,所以當(dāng)應(yīng)用在相同地方拋出相同的異常N次(兩萬(wàn)?)之后,JVM會(huì)對(duì)某些特定異常如NPE,數(shù)組越界等進(jìn)行優(yōu)化,不再帶上異常棧。此時(shí),你可能會(huì)看到日志里一條條Nul Point Exception,而真正輸出完整棧的日志早被滾動(dòng)到不知哪里去了,也就完全不知道這NPE發(fā)生在什么地方,欲哭無(wú)淚。 所以,將它禁止吧。

3.3 coredump與 -XX:ErrorFile

JVM crash時(shí),hotspot 會(huì)生成一個(gè)error文件,提供JVM狀態(tài)信息的細(xì)節(jié)。如前所述,將其輸出到固定目錄,避免到時(shí)會(huì)到處找這文件。文件名中的%p會(huì)被自動(dòng)替換為應(yīng)用的PID

-XX:ErrorFile=${MYLOGDIR}/hs_err_%p.log

當(dāng)然,更好的做法是生成coredump,從CoreDump能夠轉(zhuǎn)出Heap Dump 和 Thread Dump 還有crash的地方,非常實(shí)用。

在啟動(dòng)腳本里加上 ulimit -c unlimited或其他的設(shè)置方式,如果有root權(quán)限,設(shè)一下輸出目錄更好

echo "/{MYLOGDIR}/coredump.%p" > /proc/sys/kernel/core_pattern

什么?你不知道這coredump有什么用?看來(lái)你是沒遇過(guò)JVM Segment Fault的幸福人。

3.4-XX:+HeapDumpOnOutOfMemoryError

在Out Of Memory,JVM快死快死掉的時(shí)候,輸出Heap Dump到指定文件。不然開發(fā)很多時(shí)候還真不知道怎么重現(xiàn)錯(cuò)誤。

路徑只指向目錄,JVM會(huì)保持文件名的唯一性,叫java_pid${pid}.hprof。如果指向文件,而文件已存在,反而不能寫入。

-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=${LOGDIR}/

上文參照:

http://www.ishuo.cn/doc/oaezziqf.html

唯品會(huì)資深架構(gòu)師給你的 JVM 調(diào)優(yōu)建議

2016-10-27developerWorks|ID:28515899

本文經(jīng)開發(fā)者頭條原創(chuàng)作者 江南白衣Calvin 授權(quán)發(fā)布,著作權(quán)歸作者所有。

作者目前在唯品會(huì)擔(dān)任資深架構(gòu)師。

歡迎訂閱 江南白衣Calvin 的開發(fā)者頭條獨(dú)家號(hào)《江南白衣的Java后端架構(gòu)》

在關(guān)鍵的業(yè)務(wù)系統(tǒng)里,除了繼續(xù)追求技術(shù)人員最愛的高吞吐與低延時(shí)之外,系統(tǒng)的穩(wěn)定性與出現(xiàn)問(wèn)題時(shí)排查的便捷性也很重要。

這是本文的一個(gè)原則,后面也會(huì)一次又一次的強(qiáng)調(diào),所以與網(wǎng)上其他的文章略有不同,請(qǐng)調(diào)優(yōu)高手和運(yùn)維老大們多指引。

前言1,資料

學(xué)**開源項(xiàng)目的啟動(dòng)腳本是個(gè)不錯(cuò)的主意,比如Cassandra家的, 附送一篇解釋它的文章。

JVM調(diào)優(yōu)的"標(biāo)準(zhǔn)參數(shù)"的各種陷阱R大的文章,在JDK6時(shí)寫的,期待更新。

偶然翻到Linkedin工程師的一篇文章。

更偶然翻到的一份不錯(cuò)的參數(shù)列表。

前言2,-XX:+PrintFlagsFinal打印參數(shù)值

當(dāng)你在網(wǎng)上興沖沖找到一個(gè)可優(yōu)化的參數(shù)時(shí),先用-XX: +PrintFlagsFinal看看,它可能已經(jīng)默認(rèn)打開了,再找到一個(gè),還是默認(rèn)打開了...

JDK7與JDK8,甚至JDK7中的不同版本,有些參數(shù)值都不一樣,所以不要輕信網(wǎng)上任何文章,一切以生產(chǎn)環(huán)境同版本的JDK打出來(lái)的為準(zhǔn)。

經(jīng)常以類似下面的語(yǔ)句去查看參數(shù),偷懶不起應(yīng)用,用-version代替。有些參數(shù)設(shè)置后會(huì)影響其他參數(shù),所以查看時(shí)也把它帶上。

java -server -Xmx1024m -Xms1024m -XX:+UseConcMarkSweepGC -XX:+PrintFlagsFinal -version| grep ParallelGCThreads

前言3,關(guān)于默認(rèn)值

JDK8會(huì)默認(rèn)打開-XX:+TieredCompilation多層編譯,而JDK7則不會(huì)。JDK7u40以后的版本會(huì)默認(rèn)打開-XX:+OptimizeStringConcat優(yōu)化字符串拼接,而之前的則不打開。

對(duì)于這些參數(shù),我的建議是順勢(shì)而為,JDK在那個(gè)版本默認(rèn)打開不打開總有它的理由。安全第一,沒有很好的因由,不要隨便因?yàn)榫W(wǎng)上某篇文章的推薦(包括你現(xiàn)在在讀的這篇)就去設(shè)置。

1. 性能篇

先寫一些不那么常見的,后面再來(lái)老生常談。

1.1 取消偏向鎖 -XX:-UseBiasedLocking

JDK1.6開始默認(rèn)打開的偏向鎖,會(huì)嘗試把鎖賦給第一個(gè)訪問(wèn)它的線程,取消同步塊上的synchronized原語(yǔ)。如果始終只有一條線程在訪問(wèn)它,就成功略過(guò)同步操作以獲得性能提升。

但一旦有第二條線程訪問(wèn)這把鎖,JVM就要撤銷偏向鎖恢復(fù)到未鎖定線程的狀態(tài),詳見JVM的Stop The World,安全點(diǎn),黑暗的地底世界, 可以看到不少RevokeBiasd的紀(jì)錄,像GC一樣,會(huì)Stop The World的干活,雖然只是很短很短的停頓,但對(duì)于多線程并發(fā)的應(yīng)用,取消掉它反而有性能的提升和延時(shí)的極微的縮短,所以Cassandra就取消了它。

1.2 -XX:AutoBoxCacheMax=20000

Integer i = 3;這語(yǔ)句有著 int自動(dòng)裝箱成Integer的過(guò)程,JDK默認(rèn)只緩存 -128 ~ +127的int 和 long,超出范圍的數(shù)字就要即時(shí)構(gòu)建新的Integer對(duì)象。設(shè)為20000后,我們應(yīng)用的QPS從48,000提升到50,000,足足4%的影響。詳見Java Integer(-128~127)值的==和equals比較產(chǎn)生的思考

1.3 啟動(dòng)時(shí)訪問(wèn)并置零內(nèi)存頁(yè)面-XX:+AlwaysPreTouch

啟動(dòng)時(shí)就把參數(shù)里說(shuō)好了的內(nèi)存全部舔一遍,可能令得啟動(dòng)時(shí)慢上一點(diǎn),但后面訪問(wèn)時(shí)會(huì)更流暢,比如頁(yè)面會(huì)連續(xù)分配,比如不會(huì)在晉升新生代到老生代時(shí)才去訪問(wèn)頁(yè)面使得GC停頓時(shí)間加長(zhǎng)。不過(guò)這選項(xiàng)對(duì)大堆才會(huì)更有感覺一點(diǎn)。

1.4-XX:+PerfDisableSharedMem

Cassandra家的一個(gè)參數(shù),一直沒留意,直到發(fā)生高IO時(shí)的JVM停頓。原來(lái)JVM經(jīng)常會(huì)默默的在/tmp/hperf 目錄寫上一點(diǎn)statistics數(shù)據(jù),如果剛好遇到PageCache刷盤,把文件阻塞了,就不能結(jié)束這個(gè)Stop the World的安全點(diǎn)了。用此參數(shù)可以禁止JVM寫statistics數(shù)據(jù),代價(jià)是jps, jstat 用不了,只能用JMX取數(shù)據(jù)。有時(shí)用JMX取新生代老生代使用百分比還真沒jstat方便。詳見The Four Month Bug: JVM statistics cause garbage collection pauses

1.5 -Djava.security.egd=file:/dev/./urandom

此江湖偏方原用于Tomcat顯式使用SHA1PRNG算法時(shí),初始因子從/dev/random讀取導(dǎo)致堵塞。而使用此設(shè)置后,額外效果是默認(rèn)的SecureRandom算法也變成SHA1了。 SHA1PRNG 比 NativePRNG消耗小一半,synchronized的代碼少一半,所以沒特殊安全要求的話建議用SHA1。詳見SecureRandom的江湖偏方與真實(shí)效果

1.6 不建議的參數(shù)

1.-XX:+AggressiveOpts是一些還沒默認(rèn)打開的優(yōu)化參數(shù)集合, -XX:AutoBoxCacheMax是其中的一項(xiàng)。但如前所述,關(guān)鍵系統(tǒng)里不建議打開。雖然通過(guò)-XX:+AggressiveOpts 與 -XX:-AggressiveOpts 的對(duì)比,目前才改變了三個(gè)參數(shù),但為免以后某個(gè)版本的JDK里默默改變更多激進(jìn)的配置,還是不要了。

2. Linkined那種黑科技,先要解鎖VMOptions才能配置的就更不用說(shuō)了,比如

-XX:+UnlockDiagnosticVMOptions -XX: ParGCCardsPerStrideChunk=32768

3. JIT Compile相關(guān)的參數(shù),函數(shù)調(diào)用多少次之后開始編譯的閥值,內(nèi)聯(lián)函數(shù)大小的閥值等等,不要亂改了。

4.-XX:+UseFastAccessorMethods,JDK6的優(yōu)化,據(jù)說(shuō)在多層編譯下還慢了,所以是默認(rèn)關(guān)閉的。

5.-server,在64位linux中,你想設(shè)成-client都不行的,所以寫了也是白寫。

1.7 可選參數(shù)

1.-Djava.awt.headless=true,如果服務(wù)器上沒有屏幕,鍵盤,鼠標(biāo),又需要用到它們的時(shí)候,詳見在 Java SE 平臺(tái)上使用 Headless 模式

2.-XX:-UseCounterDecay,禁止JIT調(diào)用計(jì)數(shù)器衰減。默認(rèn)情況下,每次GC時(shí)會(huì)對(duì)調(diào)用計(jì)數(shù)器進(jìn)行砍半的操作,導(dǎo)致有些方法一直是個(gè)溫?zé)幔赡苡肋h(yuǎn)都達(dá)不到C2編譯的1萬(wàn)次的閥值。

3.-XX:-TieredCompilation,禁止JDK8默認(rèn)的多層編譯,在某些情況下因?yàn)橛行┓椒–1編譯后C2不再編譯,多層編譯反而比C2編譯慢,如果發(fā)現(xiàn)此情況可進(jìn)行禁止。

2. GC篇

2.1 GC策略

為了穩(wěn)健,還是8G以下的堆還是CMS好了,G1的細(xì)節(jié)實(shí)現(xiàn)起來(lái)難度太大,從理論提出到現(xiàn)在都做了六七年了。

CMS真正可設(shè)的東西也不多,詳見JVM實(shí)用參數(shù)(七)CMS收集器

1.基本配置

-XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=75 -XX:+UseCMSInitiatingOccupancyOnly

因?yàn)槲覀兊谋O(jiān)控系統(tǒng)會(huì)通過(guò)JMX監(jiān)控內(nèi)存達(dá)到90%的狀況(留點(diǎn)處理的時(shí)間),所以設(shè)置讓它75%就開始跑了,早點(diǎn)開始也能避免Full GC等意外情況(概念重申,這種主動(dòng)的CMS GC,和JVM的老生代、永久代、堆外內(nèi)存完全不能分配內(nèi)存了而強(qiáng)制Full GC是不同的概念)。為了讓這個(gè)設(shè)置生效,還要設(shè)置-XX:+UseCMSInitiatingOccupancyOnly,否則75只被用來(lái)做開始的參考值,后面還是JVM自己算。

2.-XX:MaxTenuringThreshold=2,這是GC里改動(dòng)效果最明顯的一個(gè)參數(shù)了。對(duì)象在Survivor區(qū)熬過(guò)多少次Young GC后晉升到年老代,JDK7里看起來(lái)默認(rèn)是6,跑起來(lái)好像變成了15。

Young GC是最大的應(yīng)用停頓來(lái)源,而新生代里GC后存活對(duì)象的多少又直接影響停頓的時(shí)間,所以如果清楚Young GC的執(zhí)行頻率和應(yīng)用里大部分臨時(shí)對(duì)象的最長(zhǎng)生命周期,可以把它設(shè)的更短一點(diǎn),讓其實(shí)不是臨時(shí)對(duì)象的新生代長(zhǎng)期對(duì)象趕緊晉升到年老代,別呆著。

-XX:+PrintTenuringDistribution觀察下,如果后面幾代都差不多,就可以設(shè)小,比如JMeter里是2。而我們的兩個(gè)系統(tǒng)里一個(gè)設(shè)了2,一個(gè)設(shè)了6。

3.-XX:+ExplicitGCInvokesConcurrent, 但不要-XX:+DisableExplicitGC, 比如Netty之堆外內(nèi)存掃盲篇,可見禁了system.gc() 未必是好事,只要自己的代碼里沒有調(diào)它,也沒用什么特別爛的類庫(kù),真有人調(diào)了總有調(diào)的原因。-XX+ExplicitGCInvokesConcurrent 則在full gc時(shí),并不全程停頓,依然只在ygc和兩個(gè)remark階段停頓,詳見JVM源碼分析之SystemGC完全解讀

4.-XX: ParallelRefProcEnabled, 默認(rèn)為false,并行的處理Reference對(duì)象,如WeakReference,除非在GC log里出現(xiàn)Reference處理時(shí)間較長(zhǎng)的日志,否則效果不會(huì)很明顯,但我們總是要JVM盡量的并行,所以設(shè)了也就設(shè)了。

2.2 GC里不建議設(shè)的參數(shù)

1.-XX:+CMSClassUnloadingEnabled,在CMS中清理永久代中的過(guò)期的Class而不等到Full GC,JDK7默認(rèn)關(guān)閉而JDK8打開。看自己情況,比如有沒有運(yùn)行動(dòng)態(tài)語(yǔ)言腳本如Groovy產(chǎn)生大量的臨時(shí)類。它會(huì)增加CMS remark的暫停時(shí)間,所以如果新類加載并不頻繁,這個(gè)參數(shù)還是不開的好。

2. 用了CMS,新生代收集默認(rèn)就是-XX:+UseParNewGC,不用自己設(shè)。

3. 并發(fā)收集線程數(shù)

ParallelGCThreads=8+( Processor - 8 ) ( 5/8 ),
ConcGCThreads = (ParallelGCThreads + 3)/4

比如雙CPU,六核,超線程就是24個(gè)處理器,小于8個(gè)處理器時(shí)ParallelGCThreads按處理器數(shù)量,大于時(shí)按上述公式ParallelGCThreads=18, ConcGCThreads=5。除了一些不在乎停頓時(shí)間的后臺(tái)輔助程序會(huì)特意把它減少,平時(shí)不建議動(dòng)。

4.-XX:+CMSScavengeBeforeRemark,默認(rèn)為關(guān)閉,在CMS remark前,先執(zhí)行一次minor GC將新生代清掉,這樣從老生代的對(duì)象引用到的新生代對(duì)象的個(gè)數(shù)就少了,停止全世界的CMS remark階段就短一些。如果看到GC日志里remark階段的時(shí)間超長(zhǎng),可以打開此項(xiàng)看看有沒有效果,否則還是不要打開了,白白多了次YGC。

5.-XX:CMSFullGCsBeforeCompaction,默認(rèn)為0,即每次full gc都對(duì)老生代進(jìn)行碎片整理壓縮。Full GC 不同于 前面設(shè)置的75%老生代時(shí)觸發(fā)的CMS GC,只在System.gc(),老生代達(dá)到100%,老生代碎片過(guò)大無(wú)法分配空間給新晉升的大對(duì)象這些特殊情況里發(fā)生,所以設(shè)為每次都進(jìn)行碎片整理是合適的,詳見此貼里R大的解釋。

2.3 內(nèi)存大小的設(shè)置

這些關(guān)于大小的參數(shù),給人感覺是最踏實(shí)可控的。

其實(shí)JVM除了顯式設(shè)置的-Xmx堆內(nèi)存,還有一堆其他占內(nèi)存的地方(堆外內(nèi)存,線程棧,永久代,二進(jìn)制代碼cache),在容量規(guī)劃的時(shí)候要留意。

關(guān)鍵業(yè)務(wù)系統(tǒng)的服務(wù)器上內(nèi)存一般都是夠的,所以盡管設(shè)得寬松點(diǎn)。

1.-Xmx, -Xms, 堆內(nèi)存大小,2~4G均可,再大了注意GC時(shí)間。

2.-Xmn or -XX:NewSize and -XX:MaxNewSize or -XX:NewRatio, JDK默認(rèn)新生代占堆大小的1/3, 個(gè)人喜歡把對(duì)半分, 增大新生代的大小,能減少GC的頻率(但也會(huì)加大每次GC的停頓時(shí)間),主要是看老生代里沒多少長(zhǎng)期對(duì)象的話,占2/3太多了。可以用-Xmn 直接賦值(等于-XX:NewSize and -XX:MaxNewSize同值的縮寫),或把NewRatio設(shè)為1來(lái)對(duì)半分(但如果想設(shè)置新生代比老生代大就只能用-Xmn)。

3.-XX: PermSize=128m -XX:MaxPermSize=512m (JDK7)現(xiàn)在的應(yīng)用有Hibernate/Spring這些鬧騰的家伙AOP之后類都比較多,可以一開始就把初始值從64M設(shè)到128M,并設(shè)一個(gè)更大的Max值以求保險(xiǎn)。

4.-XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m(JDK8),JDK8的永生代幾乎可用完機(jī)器的所有內(nèi)存,同樣設(shè)一個(gè)128M的初始值,512M的最大值保護(hù)一下。

2.4 其他內(nèi)存大小等可選設(shè)置

1.-XX:SurvivorRatio新生代中每個(gè)存活區(qū)的大小,默認(rèn)為8,即1/10的新生代 1/(SurvivorRatio+2),有人喜歡設(shè)小點(diǎn)省點(diǎn)給新生代,但要避免太小使得存活區(qū)放不下臨時(shí)對(duì)象而要晉升到老生代,還是從GC Log里看實(shí)際情況了。

2.-Xss在堆之外,線程占用棧內(nèi)存,默認(rèn)每條線程為1M(以前是256K)。存放方法調(diào)用出參入?yún)⒌臈#植孔兞浚瑯?biāo)量替換后掉局部變量等,有人喜歡設(shè)小點(diǎn)節(jié)約內(nèi)存開更多線程。但反正內(nèi)存夠也就不必要設(shè)小,有人喜歡再設(shè)大點(diǎn),特別是有JSON解析之類的遞歸調(diào)用時(shí)不能設(shè)太小。

3.-XX:MaxDirectMemorySize,堆外內(nèi)存/直接內(nèi)存的大小,默認(rèn)為Heap區(qū)總內(nèi)存減去一個(gè)Survivor區(qū)的大小,詳見Netty之堆外內(nèi)存掃盲篇。

4.-XX:ReservedCodeCacheSize, JIT編譯后二進(jìn)制代碼的存放區(qū),滿了之后就不再編譯。JDK7默認(rèn)不開多層編譯48M,開了96M,而JDK8默認(rèn)開多層編譯240M。可以在JMX里看看CodeCache的大小,JDK7下的48M一般夠了,也可以把它設(shè)大點(diǎn),反正內(nèi)存多。

2.5 GC日志

1.基本配置

-Xloggc:/dev/shm/gc-myapplication.log -XX:+PrintGCDateStamps -XX:+PrintGCDetails

詳見JVM實(shí)用參數(shù)(八)GC日志,有人擔(dān)心寫GC日志會(huì)影響性能,但測(cè)試下來(lái)實(shí)在沒什么影響,還是留一份用來(lái)排查好。

到后來(lái),又發(fā)現(xiàn)如果遇上高IO的情況,如果GC的時(shí)候,操作系統(tǒng)正在flush pageCache 到磁盤,也可能導(dǎo)致GC log文件被鎖住,從而讓GC結(jié)束不了。所以把它指向了/dev/shm 這種內(nèi)存中文件系統(tǒng),避免這種停頓,詳見Eliminating Large JVM GC Pauses Caused by Background IO Traffic

用+PrintGCDateStamps而不是PrintGCTimeStamps,打印可讀的日期而不是時(shí)間戳。

總結(jié)

以上是生活随笔為你收集整理的JVM内存调优之监控篇的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。