JVM 性能調(diào)優(yōu)
在高性能硬件上部署程序,目前主要有兩種方式:
-
通過 64 位 JDK 來使用大內(nèi)存; -
使用若干個 32 位虛擬機建立邏輯集群來利用硬件資源。
使用 64 位 JDK 管理大內(nèi)存
堆內(nèi)存變大后,雖然垃圾收集的頻率減少了,但每次垃圾回收的時間變長。 如果堆內(nèi)存為 14 G,那么每次 Full GC 將長達數(shù)十秒。如果 Full GC 頻繁發(fā)生,那么對于一個網(wǎng)站來說是無法忍受的。
對于用戶交互性強、對停頓時間敏感的系統(tǒng),可以給 Java 虛擬機分配超大堆的前提是有把握把應(yīng)用程序的 Full GC 頻率控制得足夠低,至少要低到不會影響用戶使用。
可能面臨的問題:
-
內(nèi)存回收導(dǎo)致的長時間停頓; -
現(xiàn)階段,64 位 JDK 的性能普遍比 32 位 JDK 低; -
需要保證程序足夠穩(wěn)定,因為這種應(yīng)用要是產(chǎn)生堆溢出幾乎就無法產(chǎn)生堆轉(zhuǎn)儲快照(因為要產(chǎn)生超過 10GB 的 Dump 文件),哪怕產(chǎn)生了快照也幾乎無法進行分析; -
相同程序在 64 位 JDK 消耗的內(nèi)存一般比 32 位 JDK 大,這是由于指針膨脹,以及數(shù)據(jù)類型對齊補白等因素導(dǎo)致的。
使用 32 位 JVM 建立邏輯集群
在一臺物理機器上啟動多個應(yīng)用服務(wù)器進程,每個服務(wù)器進程分配不同端口, 然后在前端搭建一個負載均衡器,以反向代理的方式來分配訪問請求。
考慮到在一臺物理機器上建立邏輯集群的目的僅僅是為了盡可能利用硬件資源,并不需要關(guān)心狀態(tài)保留、熱轉(zhuǎn)移之類的高可用性能需求, 也不需要保證每個虛擬機進程有絕對的均衡負載,因此使用無 Session 復(fù)制的親合式集群是一個不錯的選擇。 我們僅僅需要保障集群具備親合性,也就是均衡器按一定的規(guī)則算法(一般根據(jù) SessionID 分配) 將一個固定的用戶請求永遠分配到固定的一個集群節(jié)點進行處理即可。
可能遇到的問題:
-
盡量避免節(jié)點競爭全局資源,如磁盤競爭,各個節(jié)點如果同時訪問某個磁盤文件的話,很可能導(dǎo)致 IO 異常; -
很難高效利用資源池,如連接池,一般都是在節(jié)點建立自己獨立的連接池,這樣有可能導(dǎo)致一些節(jié)點池滿了而另外一些節(jié)點仍有較多空余; -
各個節(jié)點受到 32 位的內(nèi)存限制; -
大量使用本地緩存的應(yīng)用,在邏輯集群中會造成較大的內(nèi)存浪費,因為每個邏輯節(jié)點都有一份緩存,這時候可以考慮把本地緩存改成集中式緩存。
調(diào)優(yōu)案例分析與實戰(zhàn)
場景描述
一個小型系統(tǒng),使用 32 位 JDK,4G 內(nèi)存,測試期間發(fā)現(xiàn)服務(wù)端不定時拋出內(nèi)存溢出異常。 加入 -XX:+HeapDumpOnOutOfMemoryError(添加這個參數(shù)后,堆內(nèi)存溢出時就會輸出異常日志), 但再次發(fā)生內(nèi)存溢出時,沒有生成相關(guān)異常日志。
分析
在 32 位 JDK 上,1.6G 分配給堆,還有一部分分配給 JVM 的其他內(nèi)存,直接內(nèi)存最大也只能在剩余的 0.4G 空間中分出一部分, 如果使用了 NIO,JVM 會在 JVM 內(nèi)存之外分配內(nèi)存空間,那么就要小心“直接內(nèi)存”不足時發(fā)生內(nèi)存溢出異常了。
直接內(nèi)存的回收過程
直接內(nèi)存雖然不是 JVM 內(nèi)存空間,但它的垃圾回收也由 JVM 負責(zé)。
垃圾收集進行時,虛擬機雖然會對直接內(nèi)存進行回收, 但是直接內(nèi)存卻不能像新生代、老年代那樣,發(fā)現(xiàn)空間不足了就通知收集器進行垃圾回收, 它只能等老年代滿了后 Full GC,然后“順便”幫它清理掉內(nèi)存的廢棄對象。 否則只能一直等到拋出內(nèi)存溢出異常時,先 catch 掉,再在 catch 塊里大喊 “System.gc()
”。 要是虛擬機還是不聽,那就只能眼睜睜看著堆中還有許多空閑內(nèi)存,自己卻不得不拋出內(nèi)存溢出異常了。文章來源:http://www.zghlxwxcb.cn/news/detail-513742.html
JVM 性能調(diào)優(yōu)
在高性能硬件上部署程序,目前主要有兩種方式:
-
通過 64 位 JDK 來使用大內(nèi)存; -
使用若干個 32 位虛擬機建立邏輯集群來利用硬件資源。
使用 64 位 JDK 管理大內(nèi)存
堆內(nèi)存變大后,雖然垃圾收集的頻率減少了,但每次垃圾回收的時間變長。 如果堆內(nèi)存為 14 G,那么每次 Full GC 將長達數(shù)十秒。如果 Full GC 頻繁發(fā)生,那么對于一個網(wǎng)站來說是無法忍受的。
對于用戶交互性強、對停頓時間敏感的系統(tǒng),可以給 Java 虛擬機分配超大堆的前提是有把握把應(yīng)用程序的 Full GC 頻率控制得足夠低,至少要低到不會影響用戶使用。
可能面臨的問題:
-
內(nèi)存回收導(dǎo)致的長時間停頓; -
現(xiàn)階段,64 位 JDK 的性能普遍比 32 位 JDK 低; -
需要保證程序足夠穩(wěn)定,因為這種應(yīng)用要是產(chǎn)生堆溢出幾乎就無法產(chǎn)生堆轉(zhuǎn)儲快照(因為要產(chǎn)生超過 10GB 的 Dump 文件),哪怕產(chǎn)生了快照也幾乎無法進行分析; -
相同程序在 64 位 JDK 消耗的內(nèi)存一般比 32 位 JDK 大,這是由于指針膨脹,以及數(shù)據(jù)類型對齊補白等因素導(dǎo)致的。
使用 32 位 JVM 建立邏輯集群
在一臺物理機器上啟動多個應(yīng)用服務(wù)器進程,每個服務(wù)器進程分配不同端口, 然后在前端搭建一個負載均衡器,以反向代理的方式來分配訪問請求。
考慮到在一臺物理機器上建立邏輯集群的目的僅僅是為了盡可能利用硬件資源,并不需要關(guān)心狀態(tài)保留、熱轉(zhuǎn)移之類的高可用性能需求, 也不需要保證每個虛擬機進程有絕對的均衡負載,因此使用無 Session 復(fù)制的親合式集群是一個不錯的選擇。 我們僅僅需要保障集群具備親合性,也就是均衡器按一定的規(guī)則算法(一般根據(jù) SessionID 分配) 將一個固定的用戶請求永遠分配到固定的一個集群節(jié)點進行處理即可。
可能遇到的問題:
-
盡量避免節(jié)點競爭全局資源,如磁盤競爭,各個節(jié)點如果同時訪問某個磁盤文件的話,很可能導(dǎo)致 IO 異常; -
很難高效利用資源池,如連接池,一般都是在節(jié)點建立自己獨立的連接池,這樣有可能導(dǎo)致一些節(jié)點池滿了而另外一些節(jié)點仍有較多空余; -
各個節(jié)點受到 32 位的內(nèi)存限制; -
大量使用本地緩存的應(yīng)用,在邏輯集群中會造成較大的內(nèi)存浪費,因為每個邏輯節(jié)點都有一份緩存,這時候可以考慮把本地緩存改成集中式緩存。
調(diào)優(yōu)案例分析與實戰(zhàn)
場景描述
一個小型系統(tǒng),使用 32 位 JDK,4G 內(nèi)存,測試期間發(fā)現(xiàn)服務(wù)端不定時拋出內(nèi)存溢出異常。 加入 -XX:+HeapDumpOnOutOfMemoryError(添加這個參數(shù)后,堆內(nèi)存溢出時就會輸出異常日志), 但再次發(fā)生內(nèi)存溢出時,沒有生成相關(guān)異常日志。
分析
在 32 位 JDK 上,1.6G 分配給堆,還有一部分分配給 JVM 的其他內(nèi)存,直接內(nèi)存最大也只能在剩余的 0.4G 空間中分出一部分, 如果使用了 NIO,JVM 會在 JVM 內(nèi)存之外分配內(nèi)存空間,那么就要小心“直接內(nèi)存”不足時發(fā)生內(nèi)存溢出異常了。
直接內(nèi)存的回收過程
直接內(nèi)存雖然不是 JVM 內(nèi)存空間,但它的垃圾回收也由 JVM 負責(zé)。
垃圾收集進行時,虛擬機雖然會對直接內(nèi)存進行回收, 但是直接內(nèi)存卻不能像新生代、老年代那樣,發(fā)現(xiàn)空間不足了就通知收集器進行垃圾回收, 它只能等老年代滿了后 Full GC,然后“順便”幫它清理掉內(nèi)存的廢棄對象。 否則只能一直等到拋出內(nèi)存溢出異常時,先 catch 掉,再在 catch 塊里大喊 “System.gc()
”。 要是虛擬機還是不聽,那就只能眼睜睜看著堆中還有許多空閑內(nèi)存,自己卻不得不拋出內(nèi)存溢出異常了。
本文由 mdnice 多平臺發(fā)布文章來源地址http://www.zghlxwxcb.cn/news/detail-513742.html
到了這里,關(guān)于JVM 性能調(diào)優(yōu)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!