衡阳派盒市场营销有限公司

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

如何解決JDK8小版本升級后性能下降的問題

Rokr_wireless_t ? 來源:openEuler ? 作者:openEuler ? 2021-07-26 14:44 ? 次閱讀

編者按:在升級 JDK8U 的小版本后(從 8u74 升級到 8u202),遇到性能劇烈下降的問題(性能下降 13 倍)。該應用是一個非常簡單的 Web 應用,且應用在 JDK 升級前后并無任何發布修復。

通常來說 JDK 小版本升級都是問題修改,不影響功能和性能使用,而應用性能劇烈下降一定是 JDK 的內部 bug。對于這樣明確由 JDK 引起的性能問題,該如何解決?

最常見的方法是通過工具分析 JVM 執行過程,檢查函數執行的情況是否發生變化,如果找到變化,則可以深入分析哪些因素引起了變化,并進一步得到根因。筆者使用 perf 工具分析 JVM 執行時的熱點函數,并對出現問題的函數進行剖析,使用函數插樁來分析函數的執行次數,發現不同版本行為差異的根源,并找到了引起問題的根因。希望讀者遇到性能問題時可以參照本文使用 perf 工具對問題進行定位。

工欲善其事,必先利其器。程序員在定位性能瓶頸的時候,要是有一個趁手的性能調優工具,能一針見血地指出程序的性能問題,可謂事半功倍。

Linux 中最常用的性能調優工具 Perf(Linux 系統原生提供的性能分析工具),使用 perf 先對應用(假設要采樣的應用為 JavaApp)進行采樣,使用 record 命令,如下:

perfrecordjavaJavaApp

另外 perf 能按出現的百分比降序打印 CPU 正在執行的函數名以及調用棧,如命令:

perfreport-n

這種結果的輸出還是不直觀的,Linux 性能優化大師 Brendan Gregg 發明了火焰圖(因整個圖形看起來像燃燒的火焰而得名),以全局的方式來看各個函數的調用時間分布,以圖形化的方式列出調用棧。

火焰圖是基于 perf 的結果生成的圖形,我們先了解一下怎么去看火焰圖。

X 軸表示被抽樣到的次數。理解 X 軸的含義,需先了解采樣數據的原理。Perf 是在指定時間段內,每隔一段時間采集一次數據,被采集到的次數越多,說明該函數的執行總時間長,可能的原因有:調用次數多,或者單次執行時間長。因此,X 軸的寬度不能簡單的認為是運行時長。Y 軸表示調用棧。

如何從火焰圖看出性能的瓶頸在哪里?最有理由懷疑的地方,頂層的“平頂”。關于 perf 和火焰圖使用方法可以參官網http://www.brendangregg.com/FlameGraphs/cpuflamegraphs.html。

下面是我們利用火焰圖來定位問題的一次實戰。

火焰圖定位問題的實戰

問題場景

問題發生的場景是客戶端向服務器發起 http 請求,服務器返回數據給客戶端(這是一個非常簡單的服務交互)。我們發現使用 JDK 8u74 的性能要遠優于 JDK 8u202 的性能,下表中統計了 20 次服務器的響應時長。

009cbc14-e029-11eb-9e57-12bb97331649.png

從響應時間來看,8u202 相比 8u74 性能下降 13 倍之多,由于應用本身并未做任何修改,所以考慮使用火焰圖來定位性能消耗的問題點。在 8u74 和 8u202 分別運行應用,并用 perf 的 record 抓取數據并生成火焰圖。

火焰圖定位

對比兩張火焰圖,使用 8u74 時 ClientHandshaker.processMessage 占比為 1.15%,而在 8u202 中這個函數占比為 23.98%,很明顯在 ClientHandshaker.processMessage 帶來了性能差異。

00c5357c-e029-11eb-9e57-12bb97331649.png

01225572-e029-11eb-9e57-12bb97331649.png

根因定位

兩者在這個 ClientHandshaker.processMessage 上的 cpu 消耗差異很大,繼續分析這個函數找到根因。

voidprocessMessage(bytehandshakeType,intlength)throwsIOException{ if(this.state>=handshakeType&&handshakeType!=0){ //...異常 }else{ label105: switch(handshakeType){ case0://hello_request this.serverHelloRequest(newHelloRequest(this.input)); break; //... case2://sever_hello this.serverHello(newServerHello(this.input,length)); break; case11:///certificate this.serverCertificate(newCertificateMsg(this.input)); this.serverKey=this.session.getPeerCertificates()[0].getPublicKey(); break; case12://server_key_exchange該消息并不是必須的,取決于協商出的key交換算法 //... case13://certificate_request客戶端雙向驗證時需要 //... case14://server_hello_done this.serverHelloDone(newServerHelloDone(this.input)); break; case20://finished this.serverFinished(newFinished(this.protocolVersion,this.input,this.cipherSuite)); } if(this.state

processMessage()主要是通過不同的信息類型進行不同的握手消息的處理。而在火焰圖中可以看到,JDK8u74 圖中,主要消耗在函數 serverFinished()和 serverHello()上,而 JDK8u202 主要消耗在函數 serverHelloDone()和 serverKeyExchange()。

在介紹火焰圖的時候,我們有提到,X 軸的長度是映射了被采樣到的次數。因此需要進一步確定消耗:函數單次執行耗時過長而成為熱點,還是因為頻繁調用函數導致函數耗時過長而成為熱點。

可通過字節碼插樁(通過 Instrument 技術實現對函數的計數,然后編譯成 agent,執行應用時加載 agent,具體使用 Instrument 的方法可以參考官方文檔)查看函數 serverHelloDone()的調用次數及執行時間。

JDK8u202數據 Executecount:253 Executecount:258 Executecount:649 Executecount:661 serverHelloDoneexecutetime[1881195ns] Executecount:1223 Executecount:1234 Executecount:1843 Executecount:1852 serverHelloDoneexecutetime[1665012ns] Executecount:2446 Executecount:2456 serverHelloDoneexecutetime[1686206ns] JDK8u74數據 Executecount:56 Executecount:56 Executecount:56 Executecount:56 Executecount:56 Executecount:56

Execute time 是取了每 1000 次調用的平均值,Execute count 每 5000ms 輸出一次總執行次數。很明顯使用 JDK8u202 時在不斷調用 serverHelloDone,而 74 在調用 56 次后沒有再調用過這個函數。

初始化握手時,serverHelloDone 方法中,客戶端會根據服務端返回加密套件決定加密方式,構造不同的 Client Key Exchange 消息;服務器如果允許重用該會話,則通過在 Server Hello 消息中設置相同的會話 ID 來應答。

這樣,客戶端和服務器就可以利用原有會話的密鑰和加密套件,不必重新協商,也就不再走 serverHelloDone 方法。從現象來看, JDK8u202 沒有復用會話,而是建立的新的會話。

水落石出

查看 JDK8u 161 的 release notes,添加了 TLS 會話散列和擴展主密鑰擴展支持,找到引入的一個還未修復的 issue,對于帶有身份驗證的 TLS 的客戶端,支持 UseExtendedMasterSecret 會破壞 TLS-Session 的恢復,導致不使用現有的 TLS-Session,而執行新的 Handshake。

JDK8u161 之后的版本(含 JDK8u161),若復用會話時不能成功恢復 Session,而是創建新的會話,會造成較大性能消耗,且積壓的大量的不可復用的 session 造成 GC 壓力變大;如果業務場景存在不變更證書密鑰,需要復用會話,且對性能有要求,可通過添加參數-Djdk.tls.useExtendedMasterSecret=false 來解決這個問題。

后記

如果遇到相關技術問題(包括不限于畢昇 JDK),可以通過畢昇 JDK 社區求助。畢昇 JDK 社區每雙周周二舉行技術例會,同時有一個技術交流群討論 GCC、LLVM 和 JDK 等相關編譯技術,感興趣的同學可以添加如下微信小助手入群(請備注:Complier)。

編輯:jq

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • jdk8
    +關注

    關注

    0

    文章

    4

    瀏覽量

    1936

原文標題:使用 perf 解決 JDK8 小版本升級后性能下降的問題

文章出處:【微信號:wireless-tag,微信公眾號:啟明云端科技】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    motorBench 2.45.0版本說明

    電子發燒友網站提供《motorBench 2.45.0版本說明.pdf》資料免費下載
    發表于 01-22 16:15 ?0次下載
    motorBench 2.45.0<b class='flag-5'>版本</b>說明

    OurBMC 24.12版本正式上線

    日前,經過社區開發者的共同努力,OurBMC 全新升級,24.12版本正式上線。
    的頭像 發表于 01-07 13:45 ?179次閱讀

    R60AFD1跌倒雷達全新固件127版本,精準升級新體驗

    云帆瑞達頂裝跌倒雷達R60AFD1-V,全新固件版本1.27已升級。此次升級專注于算法固件的優化,未對硬件進行改動,但由于算法變化較大,無法支持前期舊版本OTA
    的頭像 發表于 11-28 15:12 ?244次閱讀
    R60AFD1跌倒雷達全新固件127<b class='flag-5'>版本</b>,精準<b class='flag-5'>升級</b>新體驗

    機器視覺 歡創播報 華為高階智能駕駛3.0版本8月上市

    1 華為高階智能駕駛3.0版本8月上市 據媒體報道,華為常務董事、智能汽車解決方案BU董事長余承東在AITO問界第40萬輛新車下線暨M9第7萬輛交付儀式上透露,將在8月份正式上市華為高階智能駕駛
    的頭像 發表于 08-01 13:59 ?681次閱讀
    機器視覺 歡創播報  華為高階智能駕駛3.0<b class='flag-5'>版本</b><b class='flag-5'>8</b>月上市

    RaftKeeper v2.1.0版本發布,性能大幅提升!

    ClickHouse 場景中,用于解決 ZooKeeper 的性能瓶頸問題,同時 RaftKeeper 也可以用于其它大數據組件比如 HBase。 v2.1.0 作為 v2.0.0 的重要版本,引入了一系列
    的頭像 發表于 07-15 15:10 ?382次閱讀
    RaftKeeper v2.1.0<b class='flag-5'>版本</b>發布,<b class='flag-5'>性能</b>大幅提升!

    OTA升級重啟版本不切換問題怎么解決?

    我用自己搭的http server作為ota升級服務器,可以看到版本正確的被下載和寫到flash,最后crc校驗也成功,信息如下: upgrade data load finish. img_crc
    發表于 07-12 08:41

    升級到RTOS SDK v1.5版本編譯報錯如何解決?

    準備升級到RTOS SDK v1.5版本,在進行工程編譯的時候出現問題,cJSON.c使用了floor和pow兩個方法,并且該文件#include ,但在鏈接的時候庫中找不到這兩個方法的定義,出現
    發表于 07-12 06:10

    JDK8升級JDK11最全實踐干貨來了

    呢?值得我們升級嗎?而且升級過程會遇到哪些問題呢?帶著這些問題,本篇文章將帶來完整的JDK8升級JDK11最全實踐。 2、為什么
    的頭像 發表于 06-25 14:51 ?527次閱讀
    <b class='flag-5'>JDK8</b><b class='flag-5'>升級</b><b class='flag-5'>JDK</b>11最全實踐干貨來了

    JDK11升級JDK17最全實踐干貨來了

    解決你的問題。 上篇文章給大家帶來了JDK8升級JDK11的最全實踐,相信大家閱讀后已經對JDK11有了比較深入的了解。2021年9月14日,Oracle發布了可以長期支持的
    的頭像 發表于 06-25 14:50 ?795次閱讀
    <b class='flag-5'>JDK</b>11<b class='flag-5'>升級</b><b class='flag-5'>JDK</b>17最全實踐干貨來了

    stm32cubemx升級到6.10.0,不能打開以前版本的文件了,怎么解決?

    stm32cubemx升級到6.10.0,不能打開以前版本的文件了,怎么解決?
    發表于 05-17 11:24

    FogCloud正式發布5.0版本,全面升級性能與服務!

    全新 FogCloud V5.0 如約而至,它不僅延續了一貫的卓越性能與用戶體驗,更在性能優化、穩定性提升及功能創新上實現了重大突破。 在此版本中,慶科信息對功能模塊進行了深度挖掘和全面升級
    的頭像 發表于 04-24 11:54 ?359次閱讀
    FogCloud正式發布5.0<b class='flag-5'>版本</b>,全面<b class='flag-5'>升級</b><b class='flag-5'>性能</b>與服務!

    蘋果停iOS 16.7.6驗證,僅支持16.7.7版本驗證

    據悉,蘋果已于4月17日停止了對iOS 16.7.6版本的驗證服務。對于已升級至iOS 16.7.7版本的iPhone用戶來說,他們已無法返回至舊版系統。
    的頭像 發表于 04-17 10:27 ?1226次閱讀

    stm32cubeIDE 1.6.1 ioc中的字體很大如何解決?

    今天把stm32cubeIDE 升級到1.6.1版本,就出現打開.ioc配置界面中的字體很大,設置的內容一屏只能放下幾項的問題,請問大家有知道如何解決這個問題嗎?之前的版本么有這個問題
    發表于 04-07 06:31

    升級STM32WB55 dongle FUS版本遇到的疑問求解

    的,我升級一下FUS版本,發現fus oprerator版本,還是空的,這里面的這個fus oprerator版本怎么升級呢,有哪位大佬可以
    發表于 03-13 07:58

    升級了STM32CubeMX到6.10版本,結果側面升級和安裝SDK庫點擊無效了怎么解決?

    升級了STM32CubeMX到6.10版本,結果側面升級和安裝SDK庫點擊無效了,賬戶登錄也點擊出不來,重裝6.9.2版本就都可以。
    發表于 03-08 06:27
    高尔夫百家乐的玩法技巧和规则| 百家乐官网庄最高连开几把| 大发888官网 888| 户型风水不好害死人 24种破财户| TT娱乐城开户,| 百家乐实战玩法| 百家乐官网视频官网| A8百家乐的玩法技巧和规则| 百家乐官网公式与赌法| 白金会娱乐场怎么样| 易胜博百家乐娱乐城| 二代百家乐官网破解| 百家乐免费下| 百家乐官网家乐娱乐城| 盐源县| 百家乐赌博论坛在线| 凯发百家乐官网是否是程序控制| 大发888娱乐城 qq服务| 3U百家乐娱乐城| 在线百家乐官网技巧| 大发888免费下载| 真人百家乐园| 聚众玩百家乐官网的玩法技巧和规则| e世博线上娱乐| 威尼斯人娱乐中心老品牌| 做生意的人早晨讲究| 网站百家乐官网博彩| 新葡京线上娱乐| 百家乐牡丹娱乐城| 百家乐官网代理| 澳门百家乐官网赢钱秘| bet365提款| 伯爵百家乐娱乐| 百家乐官网tt娱乐场开户注册 | 百家乐官网赌博代理荐| 磨丁黄金城赌场| 大发888代理| 百家乐出闲几率| 奥斯卡百家乐官网的玩法技巧和规则 | 百家乐官网小音箱| bet365客服电话|