十九.升職加薪系列-JVM優化-解決JVM性能瓶頸的JIT即時編譯器

前言

在很多年以前,做C或者C++的程序員經常說Java語言的運行速度不如C或C++,Java運行速度慢主要是因為它是解釋執行的,而C或C++是編譯執行的,解釋執行需要通過JVM虛擬機將字節碼實時翻譯成機器碼(邊翻譯邊執行),才能運行在操作系統上,這個過程會比編譯執行慢。

但現在再說這個結論就不太對了,隨著JIT即時編譯技術的發展,性能差距正在逐步縮小,甚至在某些情況下,執行速度是優于C或C++的。

一.為什么出現JIT

1.JVM代碼執行流程

我們編寫的Java程序是由以.java結尾的源文件,通過javac指令編譯為由.class結尾的字節碼文件,而字節碼文件被加載進入JVM后,是通過JVM的解釋器逐條讀取字節碼,并將其翻譯成對應平臺的機器指令執行。雖然解釋執行具有跨平臺性好、啟動速度快的特點,但其執行效率相對較低。因為每次執行字節碼時,都需要經過解釋器的翻譯過程,這增加了額外的開銷。特別是在執行循環、遞歸等熱點代碼時,性能瓶頸尤為明顯。
在這里插入圖片描述

2.JIT技術的引入

為了解決這一性能瓶頸,JVM引入了JIT即時編譯器技術。JIT技術能夠在程序運行時動態地將字節碼編譯成本地機器碼,并且根據程序的實際運行情況對機器碼進行優化,從而提高程序的執行效率。

當某些方法或代碼塊(它們都對應特定的字節碼)被頻繁調用時,這部分代碼就被視為熱點代碼。JVM虛擬機會針對性的對這部分’熱點代碼進行優化編譯,將它們從字節碼轉換為本地機器碼,然后將優化后的本地機器碼緩存起來,后續再執行時可以直接從緩存中獲取并運行,無需再次編譯。JVM提供了一個參數“-XX:ReservedCodeCacheSize”,用來限制 CodeCache 的大小。也就是說,JIT 編譯后的代碼都會放在 CodeCache 里。

在這里插入圖片描述
而熱點代碼由熱點探測進行發現,熱點探測基于計數器,JVM虛擬機會為每個方法建立對應的計數器,統計方法的執行次數、方法內的循環次數等,如果計數器超過指定閾值,則標識其為熱點代碼。

二.認識JIT即時編譯器

1.C1和C2編譯器

主流的HotSpot虛擬機內置了兩個JIT編譯器:C1(Client Compiler)編譯器和C2(Server Compiler)編譯器,C1和C2編譯器在優化方面有不同的側重點:C1側重編譯速度,C2側重深度優化

  • Client Compiler(C1):針對客戶端應用程序,優化啟動時間,以較少的編譯優化來實現更快的編譯速度。
  • Server Compiler(C2):C2編譯器側重于深度優化,與C1正好相反,C2編譯器的編譯時間較長,但優化的程度較高。C2的優化策略比較深度,會進行更高級的優化,比如逃逸分析等,C2編譯器編譯的代碼的執行速度通常比C1編譯器快。

C2編譯器由于深度優化代碼過于復雜,已經很難維護了,從JDK 10開始,Graal編譯器已經代替了C2編譯器,與C1編譯器協同工作
在這里插入圖片描述

2.JIT優化技術-熱點探測

JIT(Just-In-Time)優化技術是一種在程序運行時動態地將部分代碼編譯成機器代碼,以提高程序執行效率和性能的技術。這種技術廣泛應用于動態語言、虛擬機和一些解釋型語言的執行環境中。JIT優化技術主要包括:熱點探測,編譯優化,內聯優化,挑分析等。

熱點檢測:熱點檢測是指在程序運行時,通過監測代碼的執行情況,識別出被頻繁執行的代碼塊或方法,即熱點代碼。通過計數器記錄代碼塊或方法的執行次數,當某個代碼塊的執行次數超過一定閾值時,認為它是熱點代碼。

虛擬機為每個方法準備了兩類計數器:方法調用計數器(Invocation Counter)和回邊計數器(Back Edge Counter)。在確定虛擬機運行參數的前提下,這兩個計數器都有一個確定的閾值,當計數器超過閾值溢出了,就會觸發 JIT 編譯。

方法調用計數器

用于統計方法被調用的次數,方法調用計數器的默認閾值在客戶端模式下是 1500 次,在服務端模式下是 10000 次(我們用的都是服務端,java –version查詢),可通過 -XX: CompileThreshold 來設定

回邊計數器

用于統計一個方法中循環體代碼執行的次數,在字節碼中遇到控制流向后跳轉的指令稱為“回邊”(Back Edge),該值用于計算是否觸發 C1 編譯的閾值,在不開啟分層編譯的情況下,在服務端模式下是10700。
回邊計數器閾值 =方法調用計數器閾值(CompileThreshold)×(OSR比率(OnStackReplacePercentage)-解釋器監控比率(InterpreterProfilePercentage)/100 , 通過 java -XX:+PrintFlagsFinal –version查詢相關參數:

在這里插入圖片描述在這里插入圖片描述其中OnStackReplacePercentage默認值為140,InterpreterProfilePercentage默認值為33,如果都取默認值,那Server模式虛擬機回邊計數器的閾值為10700. 回邊計數器閾值 =10000×(140-33)=10700

3.方法內聯

將函數調用處的代碼直接插入到調用點,減少函數調用的開銷。

// 方法內聯
public int xx() {int num1 = 111;int num2 = 222;// 等價于 ->  sum = num1 + num2int sum = add(num1, num2);return sum;
}public int add(int num1, int num2) {return num1 + num1;
}

在代碼中,方法內聯會將其中的add(num1, num2)方法轉換為實際的num1 + num1,直接進行計算操作,避免了方法調用。

4.鎖消除技術

如果在線程安全的情況下使用了一個線程安全的容器那么會導致性能降低,比如StringBuffer這樣的類的append方法是有Synchronized同步鎖使的性能底下

public void xx(){SpringBuffer s = new StringBuffer();s.append(...)
}

但實際上,在以上代碼測試中,StringBuffer 和 StringBuilder 的性能基本沒什么區別。這是因為在局部方法中創建的對象只能被當前線程訪問,無法被其它線程訪問,這個變量的讀寫肯定不會有競爭,這個時候 JIT 編譯會對這個對象的方法鎖進行鎖消除。
使用StringBuffer和StringBuilder,我們把鎖消除關閉—測試發現性能差別有點大

  • -XX:+EliminateLocks開啟鎖消除(jdk1.8默認開啟,其它版本未測試)
  • -XX:-EliminateLocks 關閉鎖消除

鎖粗化

for( ... ){Synchronized(this){ ... }
}

鎖粗化的作用:如果檢測到同一個對象執行了連續的加鎖和解鎖的操作,則會將這一系列操作合并成一個更大的鎖,從而提升程序的執行效率。

5.逃逸分析技術

大家常理解的對象分配是在堆中分配的,對象的引用變量通常在棧中,當方法結束棧銷毀后,堆中對象失去引用后等待垃圾回收器回收。在某種情況下對象是可以在棧中分配的,也就是說當棧被銷毀對象也會被銷毀,這樣的話大大減少了GC的回收成本。這種對象分配就是棧上分配,是否能在棧上分配需要使用逃逸分析算法進行計算。
在這里插入圖片描述

逃逸分析的原理:分析對象動態作用域,當一個對象在方法中定義后,它不會被外部方法所引用(無法逃逸),那么這樣的對象會被在棧中分配,因為該對象只是在當前方法中使用,如下:

public void jjjj(){for(... : 50000){xxx();}
}
public void xxx() {User user = new User();	//棧上分配user.name = "zhangsan";user.age = 18;//to do something
}

當然逃逸分析技術屬于JIT的優化技術,所以必須要符合熱點代碼,JIT才會優化,另外對象如果要分配到棧上,需要將對象拆分(大對象放不下需要拆解),這種編譯優化就叫做標量替換技術。

也就是說:要滿足棧中分配需要滿足2個條件,一是熱點代碼 ,而是標量替換。

  • -XX:+DoEscapeAnalysis開啟逃逸分析(jdk1.8默認開啟)
  • -XX:-DoEscapeAnalysis 關閉逃逸分析
  • -XX:+EliminateAllocations開啟標量替換(jdk1.8默認開啟)
  • -XX:-EliminateAllocations 關閉標量替換

三.總結

本篇文章介紹了JVM的JIT即時編譯器,它解決了解釋器在逐行解釋性能差的問題,它通過對熱點代碼的探測,將熱點代碼編譯后進行緩存,從而提高程序的執行性能。
而JIT的優化技術除了熱點代碼編譯緩存外,還提供了方法內聯,鎖消除,逃逸分析等手段來提高程序性能。

文章結束喜歡的話請給個好評!!!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/43595.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/43595.shtml
英文地址,請注明出處:http://en.pswp.cn/web/43595.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Rust 版本升級:rustup update stable 報錯

Rust 版本升級 rustup update stable 報錯 一、報錯內容 error: could not download file from ‘https://static.rust-lang.org/dist/channel-rust-stable.toml.sha256’ to ‘/Users/xxx/.rustup/tmp/rv6vdfu3eupwo64m_file’: failed to make network request: error sendi…

【實戰場景】@Transactional中使用for update的注意點

【實戰場景】Transactional中使用for update的注意點 開篇詞:干貨篇:知識回顧注意點1.鎖的范圍和粒度:2.事務的隔離級別:3.死鎖:4.性能影響:5.事務的邊界:6.異常處理:7. 數據庫和存儲…

【漏洞復現】網神 SecGate 3600 防火墻 sys_export_conf_local_save 任意文件讀取

免責聲明: 本文內容旨在提供有關特定漏洞或安全漏洞的信息,以幫助用戶更好地了解可能存在的風險。公布此類信息的目的在于促進網絡安全意識和技術進步,并非出于任何惡意目的。閱讀者應該明白,在利用本文提到的漏洞信息或進行相關測…

javaweb學習day5--《HTML篇》Springboot的模塊創建、HTML的相關知識點詳解

一、前言 從今天開始,就要啟動后端的學習了,Springboot會貫穿到底,一定要跟著小編嚴謹的去搭建Springboot環境,依賴添加的過程可能需要2分鐘左右,讀者們要耐心等待一下,搭建好Springboot之后才算正式的開始…

算力革命:彈性租賃,解鎖無限可能

華為創始人任正非曾在一場程序設計競賽中說道,我們即將進入第四次工業革命,基礎就是大算力。事實上,隨著5G、人工智能等信息技術的迅猛發展,算力需求持續增長,但高昂的成本和快速的技術迭代讓許多中小企業和個人開發者…

Covalent Network(CXT)通過社區投票將代幣遷移并更名為 CXT,以推動人工智能更深層次的創新

專注于人工智能和 Web3 的模塊化數據基礎設施 Covalent Network(CXT)宣布,其治理提案已通過社區投票并順利實施,即將原生代幣 CQT 遷移為新的 CXT 代幣,并部署至新的合約。這一關鍵性轉變標志著 Covalent Network&…

git刪除提交記錄,并使用idea將代碼重新提交到gitee倉庫

git 新建分支將之前的記錄刪除重新提交 轉載鏈接 https://blog.csdn.net/qq_37142541/article/details/139860956

03-NoSQL之Redis配置與優化

一、redis與memcache總體對比 1.性能 Redis:只使用單核,平均每一個核上Redis在存儲小數據時比Memcached性能更高。 Memcached:可以使用多核,而在100k以上的數據中,Memcached性能要高于Redis。 2.內存使用效率 MemC…

springboot文達辦公物資管理系統-計算機畢業設計源碼51191

摘要 本文介紹了一種名為"文達辦公物資管理系統"的基于JAVA語言、基于Springboot框架和MYSQL數據庫開發的管理系統。該系統主要分為管理員和員工用戶兩個角色,以滿足不同用戶的需求。 對于管理員用戶,系統提供了儀器設備管理、設備借用管理、設…

【大數據技術】換新電腦了,如何快速遷移MySQL到新電腦上(含程序+數據),這樣既快速又高效,省去了“各種安裝+各種配置+各種遷移數據”帶來的麻煩和時間

【大數據技術】換新電腦了,如何快速遷移MySQL到新電腦上(含程序數據 背景步驟總結 背景 很久沒有寫博文了哦,最近我換了新的筆記本,于是需要在新筆記本電腦上搭建MySQL環境,因為我原電腦上是安裝的MySQL解壓版,故我想偷偷懶&…

可理解性評估:使用Google Gemini優化語音識別的意義保留

每周跟蹤AI熱點新聞動向和震撼發展 想要探索生成式人工智能的前沿進展嗎?訂閱我們的簡報,深入解析最新的技術突破、實際應用案例和未來的趨勢。與全球數同行一同,從行業內部的深度分析和實用指南中受益。不要錯過這個機會,成為AI領…

nftables(5)表達式(3)PAYLOAD EXPRESSIONS

PAYLOAD EXPRESSIONS Payload expressions在nftables中扮演著重要的角色,因為它們允許用戶定義復雜的規則,這些規則可以基于數據包的內容(即有效載荷)來過濾、修改或允許數據包通過。這些表達式可以執行諸如數據拷貝、比較、位操…

實驗1 —— 安全策略的練習

實驗拓撲圖 實驗要求 1.DMZ區內的服務器,辦公區僅能在辦公時間內(9:00-18:00)可以訪問,生產區的設備全天可以訪問; 2.生產區不允許訪問互聯網,辦公區和游客區允許訪問互聯網 3.辦公區…

RabbitMQ保證消息被成功發送和消費

一 : 在使用 RabbitMQ 作為消息隊列時,保證消息被成功發送和消費是一個非常重要的問題。以下是一些關鍵點和最佳實踐,以確保消息的可靠傳輸和處理。* 配置方式: 保證消息被成功發送 確認模式(Confirm Mode):生產者可以…

在SpringBoot使用AOP防止接口重復提交

前言 防止接口重復提交有跟多種方法,可以在前端做處理。同樣在后端也能處理,而且后端的處理也有很多中方法。最先能想到的就是加鎖,也可以直接在該接口的實現過程中進行處理(可以參考防止數據重復提交的6種方法(超簡單)&#xff…

動手學Avalonia:基于硅基流動構建一個文生圖應用(一)

文生圖 文生圖,全稱“文字生成圖像”(Text-to-Image),是一種AI技術,能夠根據給定的文本描述生成相應的圖像。這種技術利用深度學習模型,如生成對抗網絡(GANs)或變換器(T…

【Mac】Charles for Mac(HTTP協議抓包工具)及同類型軟件介紹

軟件介紹 Charles for Mac 是一款功能強大的網絡調試工具,主要用于HTTP代理/HTTP監視器。以下是它的一些主要特點和功能: 1.HTTP代理:Charles 可以作為HTTP代理服務器,允許你查看客戶端和服務器之間的所有HTTP和SSL/TLS通信。 …

金航標kinghelm宋仕強在介紹自己公司時說

金航標kinghelm宋仕強在介紹自己公司時說,金航標成立于2007年,成立地點在華強北雷圳大廈803室,后搬到華強北廣業大廈24樓CD室,后搬遷到龍華展滔科技大廈C座C809和C817室,現在的辦公地址為龍崗區坂田街道百瑞達大廈&…

WSL安裝USB驅動

wsl用不了USB盤,需要安裝驅動 1、安裝windows驅動 https://github.com/dorssel/usbipd-win/releases 下載msi,并且安裝 2、linux里面安裝 sudo apt install linux-tools-5.4.0-77-generic hwdata sudo update-alternatives --install /usr/local/bin/usb…

PageDTO<T>,PageQuery,BeanUtils,CollUtils的封裝

一、PageDTO<T> import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.fasterxml.jackson.annotation.JsonIgnore; import com.tianji.common.utils.BeanUtils; import com.tianji.common.utils.CollUtils; import com.tianji.common.utils.…