JVM 第六篇:極致優(yōu)化 IDEA 啟動(dòng)速度

?本文內(nèi)容過于硬核,建議有 Java 相關(guān)經(jīng)驗(yàn)人士閱讀。
?
1. 引言
相信做 Java 開發(fā)的同學(xué),對(duì) IDEA 這個(gè)工具應(yīng)該都不陌生,即使不使用 IDEA 做開發(fā),那么對(duì) Eclipse 這個(gè)工具應(yīng)該也不會(huì)陌生,如果這兩個(gè)都不用的同學(xué),我就想弱弱問一句,您不會(huì)是在使用記事本吧?

上面除了那個(gè)記事本,我相信所有的同學(xué)都對(duì) IDEA 或者說 Eclipse 這兩個(gè)工具的打開速度深有印象吧。
只要你沒自己改過啟動(dòng)參數(shù),不管電腦多高的配置,我相信這個(gè)打開速度應(yīng)該都快不到哪去。
前面寫了這么多篇的 JVM 相關(guān)內(nèi)容,今天我嘗試優(yōu)化一下 IDEA 的啟動(dòng)速度(手頭沒有 Eclipse ),這算是小試牛刀,希望最后不要翻車。

2. 開始
我使用的是 JDK 自帶的 VisualVM 可視化工具,主要使用的是它的那個(gè) GC 插件。

首先第一次打開 IDEA ,加載時(shí)長(zhǎng)按照 IDEA 所有組件加載完成進(jìn)行人工卡點(diǎn)(本來想找個(gè)插件的,結(jié)果 IDEA 這方面的插件還真沒找到)。
IDEA 在打開的過程中,右下角會(huì)有一個(gè)進(jìn)度條在一直讀條,我就大約等那個(gè)條讀完了進(jìn)行計(jì)時(shí)。
后續(xù)操作的過程中發(fā)現(xiàn)其實(shí)完全沒必要,因?yàn)椴罹嗪?jiǎn)直太明顯了。
首先在默認(rèn)配置的情況下第一次打開 IDEA ,然后看下 VisualVM 的數(shù)據(jù)圖:
GC 情況:

概覽情況:

我直接被這個(gè) Class Loader 加載速度驚呆了,活活消耗了 3m 34s 的時(shí)間,由于其他操作都是并行的,這一項(xiàng)的耗時(shí)直接撐破天了。
不過同時(shí)可以看到 GC 的消耗,好像并不是很大, Minor GC 發(fā)生了 147 次,但是 Full GC 一次都沒有發(fā)生過,共計(jì)耗時(shí) 712ms 。
但是看到下面的概覽圖還是能發(fā)現(xiàn)一些端倪的,就比如當(dāng)前堆大小在一直不停的擴(kuò)容。
先找到 IDEA 的配置文件,看下默認(rèn)配置,我本地的路徑是 D:\Program Files\JetBrains\apps\IDEA-U\ch-0 ,這個(gè)路徑每個(gè)人都不一樣,大家自己找自己的,找到以后打開 idea64.exe.vmoptions 這個(gè)文件:
-Xms128m
-Xmx750m
-XX:ReservedCodeCacheSize=240m
-XX:+UseConcMarkSweepGC
-XX:SoftRefLRUPolicyMSPerMB=50
-ea
-XX:CICompilerCount=2
-Dsun.io.useCanonPrefixCache=false
-Djdk.http.auth.tunneling.disabledSchemes=""
-XX:+HeapDumpOnOutOfMemoryError
-XX:-OmitStackTraceInFastThrow
-Djdk.attach.allowAttachSelf=true
-Dkotlinx.coroutines.debug=off
-Djdk.module.illegalAccess.silent=true
可以看到最小堆是設(shè)置 128MB ,而最大堆是 750MB ,使用的是 CMS 收集器,我使用的電腦硬件內(nèi)存是 16GB ,這么大的內(nèi)存空間,果斷直接把最小堆改成 1G ,最大堆改成 2G ,關(guān)掉 IDEA 再重啟看下效果。
修改后的配置如下:
-Xms1g
-Xmx2g
-XX:ReservedCodeCacheSize=240m
-XX:+UseConcMarkSweepGC
-XX:SoftRefLRUPolicyMSPerMB=50
GC 情況:

概覽情況:

可以看到,Class Loader 時(shí)長(zhǎng)瞬間就下來了,從 3m 變成了 24s ,并且 Minor GC 的時(shí)長(zhǎng)整整縮短了一半,從 712ms 下降到了 342ms ,次數(shù)也由之前的 147 次下降到了現(xiàn)在的 9 次,依然沒有 Full GC 產(chǎn)生(廢話,內(nèi)存開了這么大又填不滿)。
并且看概覽圖的時(shí)候可以看到,堆內(nèi)存擴(kuò)容只擴(kuò)容了一次。
那么還能不能再短點(diǎn)呢?看下整個(gè)圖,感覺 ClassLoader 還有空間嘛,我們還可以把加載時(shí)的驗(yàn)證給關(guān)掉,使用 -Xverify:none ,這樣應(yīng)該還能再降低一些加載的耗時(shí)。
修改后的配置如下:
-Xms1g
-Xmx2g
-XX:ReservedCodeCacheSize=240m
-XX:+UseConcMarkSweepGC
-XX:SoftRefLRUPolicyMSPerMB=50
-Xverify:none
GC 情況:

概覽情況:

果然,加載時(shí)長(zhǎng)從之前的 24s 繼續(xù)下降到了 19s ,差不多減少了有 1/4 左右,還是卓有成效的。
接著我想如果直接把最小堆也設(shè)置成 2G ,那么堆大小就無需擴(kuò)容,會(huì)不會(huì)有更加正向的影響?
修改后的配置如下:
-Xms2g
-Xmx2g
-XX:ReservedCodeCacheSize=240m
-XX:+UseConcMarkSweepGC
-XX:SoftRefLRUPolicyMSPerMB=50
-Xverify:none
GC 情況:

概覽情況:

實(shí)際上并沒有什么太大成效。
從概覽中可以看到,我當(dāng)前版本的 IDEA 使用的是自帶的 JDK11 :

JDK11 中是有 G1 收集器的,我要么開啟 G1 試一下:
-Xms1g
-Xmx2g
-XX:ReservedCodeCacheSize=240m
-XX:+UseG1GC
-XX:SoftRefLRUPolicyMSPerMB=50
-Xverify:none
GC 情況:

概覽情況:

看起來好像 Minor GC 的耗時(shí)還略有上漲,并且 GC 的次數(shù)從 9 次變成了 19 次。
不過看到概覽圖發(fā)現(xiàn)了一個(gè)更神奇的事情,當(dāng)使用 G1 的時(shí)候,整個(gè)使用堆大小竟然沒有突破 1G ,看來電腦內(nèi)存不夠大的同學(xué)更加推薦使用 G1 回收器,雖然 GC 的耗時(shí)稍有增加,不過能減少內(nèi)存的使用,而 G1 的 GC 機(jī)制又是大量并行的,這點(diǎn)根本無傷大雅。
最后我放一下我修改后的整體的配置:
-Xms1g
-Xmx2g
-XX:ReservedCodeCacheSize=240m
-XX:+UseG1GC
-XX:SoftRefLRUPolicyMSPerMB=50
-Xverify:none
-ea
-XX:CICompilerCount=2
-Dsun.io.useCanonPrefixCache=false
-Djdk.http.auth.tunneling.disabledSchemes=""
-XX:+HeapDumpOnOutOfMemoryError
-XX:-OmitStackTraceInFastThrow
-Dkotlinx.coroutines.debug=off
-Djdk.module.illegalAccess.silent=true
-Dide.no.platform.update=true
-Djdk.attach.allowAttachSelf=true
-Didea.plugins.path=D:\\Program?Files\\JetBrains\\apps\\IDEA-U\\ch-0\\202.7660.26.plugins
當(dāng)然,如果不用 IDEA 的同學(xué),只要是用 Jetbrain 全家桶套件,例如寫 Python 最常用的 Pycharm ,同樣也可以按照本文的方式進(jìn)行配置,我自己又給 Pycharm 修改了一下配置,啟動(dòng)速度絕對(duì)大幅提升,肉眼可見的那種。

