JVM角度調(diào)試優(yōu)化MyEclipse
在將工作電腦的操作系統(tǒng)更換為win7之后,我的MyEclipse的啟動(dòng)速度和運(yùn)行速率一直很不理想。特別是在同時(shí)修改調(diào)試多個(gè)頁(yè)面模板的時(shí)候,來(lái)回切換兩個(gè)文件總是會(huì)卡個(gè)十來(lái)秒。試過(guò)關(guān)掉各種插件和驗(yàn)證也無(wú)濟(jì)于事。于是在大致的研究完JVM后,決定從JVM的角度來(lái)試著解決這個(gè)問(wèn)題。
啟動(dòng)優(yōu)化:
首先來(lái)看下我的myeclipse.ini里面的默認(rèn)啟動(dòng)參數(shù):
-Xmx512m :設(shè)置堆內(nèi)存最大值為512M
-XX:MaxPermSize=256m :設(shè)置持久代最大值為256m
-XX:ReservedCodeCacheSize=64m :設(shè)置代碼占用的內(nèi)存大小為64m
從啟動(dòng)參數(shù)上看不出什么,于是往里面加入打印內(nèi)存變化相關(guān)參數(shù):
-XX:+PrintGCTimeStamps : 打印每次GC的時(shí)間戳
-XX:+PrintGCDetails : 打印每次GC的詳細(xì)信息
-Xloggc:myEclipseGC.log :將GC的記錄輸出到文件
-verbose:gc : 輸出每次GC的相關(guān)情況
然后啟動(dòng)MyEclipse,然后查看myEclipseGC.log里面的信息:
啟動(dòng)耗時(shí)大概在30秒左右,選擇性的截取一小部分日志,可以看到,在myeclipse啟動(dòng)的前10秒內(nèi),JVM總共執(zhí)行了300多次的GC和9次的FULL GC。
從GC頻率和信息可以看出內(nèi)存的回收率很高,且大小在不斷調(diào)整,這應(yīng)該是由于年輕代的空間不足導(dǎo)致,需要設(shè)定一個(gè)不小的初始值。
然后來(lái)重點(diǎn)關(guān)注FULL GC:
9.030: [Full GC 9.030: [Tenured: 53310K->52332K(64588K), 0.2034757 secs] 56020K->52332K(69516K), [Perm : 43007K->42996K(43008K)], 0.2036030 secs] [Times: user=0.20 sys=0.00, real=0.20 secs]
從兩次日志的對(duì)比中可以看到,F(xiàn)ULL GC主要是在回收Tenured和Perm這兩個(gè)區(qū)域,并且這兩個(gè)區(qū)域的大小都在不斷的調(diào)整中,所以決定先把它們的大小固定下來(lái)。
于是調(diào)整后的參數(shù)如下:
-Xms512m :設(shè)定堆的最小值為512m
-Xmn192m : 設(shè)定年輕代的大小為192m
-XX:PermSize=192m : 設(shè)定持久代的初始值為192m
-XX:MaxPermSize=192m
-XX:ReservedCodeCacheSize=64m
-XX:+PrintGCTimeStamps
-XX:+PrintGCDetails
-Xloggc:myEclipseGC.log
-verbose:gc
重新啟動(dòng)一次MyEclipse,查看日志信息:
啟動(dòng)耗時(shí)12秒左右,從日志可以看出,在前10秒內(nèi)總共只進(jìn)行了5次GC,不涉及各區(qū)域大小的調(diào)整,這個(gè)結(jié)果還是可以接受的,因?yàn)楣ぷ鲿r(shí)不怎么需要頻繁重啟。
工作響應(yīng)速度優(yōu)化:
接下來(lái)研究困擾了我很久的來(lái)回切換html文件時(shí)的經(jīng)常性延時(shí)和大卡問(wèn)題,為了更直觀的研究JVM的內(nèi)存變化,決定借助jconsole這個(gè)java自帶的輔助工具。先把myeclipse.ini的參數(shù)還原,避免被第一階段的優(yōu)化干擾。
啟動(dòng)myeclipse,啟動(dòng)jconsole并接入myeclipse所在的JVM,穩(wěn)定后的整個(gè)堆的內(nèi)存圖如下:
接下來(lái)試著打開(kāi)幾個(gè)模板,然后觀察內(nèi)存的變化。
首先是堆內(nèi)存的整體使用情況:
可以看到,在打開(kāi)了幾個(gè)模板之后,堆內(nèi)存的使用從原先的100M以下突增至300M以上。使用量增加了三倍,但是還在我設(shè)置的512M范圍之內(nèi)。所以可以暫時(shí)不考慮繼續(xù)增加堆內(nèi)存,轉(zhuǎn)而考慮調(diào)整各區(qū)內(nèi)存大小比例問(wèn)題。
于是觀察下各個(gè)區(qū)在這段時(shí)間的內(nèi)存使用情況,其中,Eden區(qū)如下:
Eden區(qū)在這段時(shí)間的內(nèi)存使用率大增,且發(fā)生了多次GC。通過(guò)底下的監(jiān)控信息可以知道,eden區(qū)在默認(rèn)情況下只分配了31M的最大內(nèi)存,這顯然是不夠用的。稍微執(zhí)行點(diǎn)操作都會(huì)觸發(fā)eden區(qū)的GC,這應(yīng)該是模板打開(kāi)切換發(fā)生延時(shí)卡頓的原因之一,需要調(diào)整。
接下來(lái)是Tenured區(qū):
JVM默認(rèn)給這個(gè)區(qū)域分配的最大空間是470M。隨著內(nèi)存使用的變化,這個(gè)區(qū)域的實(shí)際大小一直在調(diào)整,每次區(qū)域大小的調(diào)整都會(huì)發(fā)生FULL GC,這應(yīng)該是經(jīng)常性大卡的原因之一。而新模板的打開(kāi)是觸發(fā)這種調(diào)整的主要原因。從這個(gè)區(qū)域內(nèi)存的使用上來(lái)看,將這個(gè)區(qū)域的內(nèi)存空間維持并固定在450M左右,保持一定的冗余還是有必要的。
從這點(diǎn)來(lái)看,jvm的堆內(nèi)存還是有必要稍微擴(kuò)充下以維持一個(gè)較大的Tenured區(qū)和Eden區(qū)。
最后來(lái)看下perm區(qū):
作為方法區(qū)的一部分,這個(gè)區(qū)域的內(nèi)存變化并不大,并且比較穩(wěn)定,本來(lái)不需要留太多的冗余。但是考慮到當(dāng)前打開(kāi)的工程實(shí)際代碼量并不大,決定暫時(shí)維持在128M左右,日后慢慢調(diào)整。
于是根據(jù)上面的分析將參數(shù)調(diào)整為:
-Xmx768m
-Xms768m
-Xmn256m
-XX:PermSize=192m
-XX:MaxPermSize=192m
-XX:ReservedCodeCacheSize=64m
重啟myeclipse,接入Jconsole,同時(shí)打開(kāi)三十來(lái)個(gè)模板做了下測(cè)試。在觀查各個(gè)區(qū)的內(nèi)存使用率時(shí)發(fā)現(xiàn)一個(gè)問(wèn)題,在將年輕代調(diào)整為256M以后,由于Eden不再頻繁的發(fā)生GC,進(jìn)入 Tenured區(qū)的數(shù)據(jù)量明顯減少 ,Tenured區(qū)的內(nèi)存使用圖如下:
如上圖,在特意打開(kāi)很多模板的情況下,450M+的空間只使用了不到250M,空間利用率太低,需再做調(diào)整。
總結(jié)
以上是我對(duì)自己的myeclipse進(jìn)行調(diào)優(yōu)的一些思路和實(shí)際調(diào)優(yōu)的過(guò)程,在實(shí)際使用中又根據(jù)自己的喜好進(jìn)行了一些調(diào)整定制,最終形成的myeclipse.ini的參數(shù)如下:
-vmargs
-Xmx512m
-Xms512m
-Xmn192m
-XX:PermSize=128m
-XX:MaxPermSize=128m
-XX:ReservedCodeCacheSize=64m
在這個(gè)參數(shù)設(shè)置下,myeclipse的響應(yīng)速度比較有保證,各種延時(shí)卡頓的現(xiàn)象的出現(xiàn)頻率大大降低。缺點(diǎn)是常駐的占用的系統(tǒng)內(nèi)存偏高,喜歡同時(shí)打開(kāi)多個(gè)myeclipse的同學(xué)可根據(jù)自己的需要和實(shí)際情況進(jìn)行適當(dāng)?shù)恼{(diào)整。
以上就是本文的全部?jī)?nèi)容,希望能夠?qū)Υ蠹业膶W(xué)習(xí)有所幫助。
相關(guān)文章
詳解Java中方法next()和nextLine()的區(qū)別與易錯(cuò)點(diǎn)
這篇文章主要介紹了詳解Java中方法next()和nextLine()的區(qū)別與易錯(cuò)點(diǎn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11Spring監(jiān)聽(tīng)器及定時(shí)任務(wù)實(shí)現(xiàn)方法詳解
這篇文章主要介紹了Spring監(jiān)聽(tīng)器及定時(shí)任務(wù)實(shí)現(xiàn)方法詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-07-07Spring Boot使用RestTemplate消費(fèi)REST服務(wù)的幾個(gè)問(wèn)題記錄
這篇文章主要介紹了Spring Boot使用RestTemplate消費(fèi)REST服務(wù)的幾個(gè)問(wèn)題記錄,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-06-06mybatis使用collection嵌套查詢的實(shí)現(xiàn)
本文主要介紹了mybatis使用collection嵌套查詢的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-05-05在java8中使用流區(qū)分質(zhì)數(shù)與非質(zhì)數(shù)詳解
這篇文章主要介紹了在java8中使用流區(qū)分質(zhì)數(shù)與非質(zhì)數(shù)詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-12-12詳解Java基礎(chǔ)篇--面向?qū)ο?(構(gòu)造方法,static、this關(guān)鍵字)
這篇文章主要介紹了Java基礎(chǔ)篇--面向?qū)ο?(構(gòu)造方法,static、this關(guān)鍵字),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04Java中實(shí)現(xiàn)文件上傳下載的三種解決方案(推薦)
這篇文章主要介紹了Java中實(shí)現(xiàn)文件上傳下載的三種解決方案的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-07-07