讀Java性能權威指南(第2版)筆記07_即時編譯器上

来源:https://www.cnblogs.com/lying7/archive/2023/03/03/17165660.html
-Advertisement-
Play Games

1. 概覽 1.1. 即時編譯器是Java虛擬機的核心 1.1.1. just-in-time compiler,簡稱JIT compiler 1.1.2. 即時編譯器會頻繁地使用寄存器 1.2. 編譯型語言 1.2.1. 程式是以二進位(編譯後的)代碼的形式發佈的 1.2.1.1. 彙編代碼是針對 ...


1. 概覽

1.1. 即時編譯器是Java虛擬機的核心

1.1.1. just-in-time compiler,簡稱JIT compiler

1.1.2. 即時編譯器會頻繁地使用寄存器

1.2. 編譯型語言

1.2.1. 程式是以二進位(編譯後的)代碼的形式發佈的

1.2.1.1. 彙編代碼是針對特定CPU的

1.2.1.2. 相容的CPU可以執行同一個二進位文件

1.2.2. 如C++和Fortran

1.3. 解釋型語言

1.3.1. 同樣的程式源代碼就可以在任何CPU上運行

1.3.2. 如PHP和Perl

1.4. 中間地帶

1.4.1. 編譯為一種中間的低級語言

1.4.1.1. Java位元組碼

1.4.1.2. 由JVM進一步編譯成彙編語言

1.4.2. 利用了腳本語言的平臺獨立性和編譯型語言的原生性能

1.4.3. 在代碼執行時將其編譯為平臺相關的二進位代碼

1.4.3.1. 是“即時”的

1.5. 熱點編譯

1.5.1. 只有一小部分代碼會頻繁執行,應用程式的性能則主要取決於這些代碼執行的快慢

1.5.2. 關鍵代碼被稱為應用程式的熱點

1.5.2.1. 這部分代碼執行得越多,就說這部分代碼越熱

1.5.3. 只執行一次的代碼,解釋執行Java位元組碼會更快一點

1.5.4. 代碼是頻繁調用的方法或者迭代多次的迴圈,編譯它就是值得的

2. 分層編譯

2.1. 現在所有JVM都在使用的技術

2.2. -XX:-TieredCompilation標誌

2.2.1. 預設值是true

2.3. 兩種類型

2.3.1. client編譯器

2.3.1.1. C1編譯器1

2.3.2. server編譯器

2.3.2.1. C2編譯器2

2.4. 編譯代碼的時機

2.4.1. 基於程式會運行多長時間和程式的啟動時間有多重要

2.4.2. C1編譯器比C2編譯器更早開始編譯

2.4.3. 在代碼執行的開始階段,C1編譯器的速度更快

2.4.4. C2編譯器在等待時獲得了信息,這些信息讓C2編譯器能夠對編譯後的代碼進行更好的優化

3. 編譯器標誌

3.1. 代碼緩存

3.1.1. 一種設定了最大值的系統資源

3.1.2. 影響JVM可以運行的編譯後的代碼總量

3.1.3. 最大值

3.1.3.1. -XX:ReservedCodeCacheSize=N

3.1.3.2. 預設240 MB

3.1.4. 初始大小

3.1.4.1. -XX:InitialCodeCacheSize=N

3.1.4.2. 預設2496 KB

3.2. Java 11中

3.2.1. 非方法代碼(nonmethod code)

3.2.1.1. -XX:NonMethodCodeHeapSize=N

3.2.2. 性能分析代碼(profiled code)

3.2.2.1. -XX:ProfiledCodeHeapSize=N

3.2.3. 非性能分析代碼(nonprofiled code)

3.2.3.1. -XX:NonProfiledCodeHeapSize=N

3.3. 檢查編譯過程

3.3.1. 不是用來優化的,它不會提升應用程式的性能

3.3.2. -XX:+PrintCompilation標誌

3.3.2.1. 預設為false

3.3.3. attributes欄位由5個字元構成,表示正在編譯的代碼狀態

3.3.3.1. %

3.3.3.1.1. 棧上替換(on-stack replacement,OSR)

3.3.3.2. s

3.3.3.2.1. 方法是同步的

3.3.3.3. !

3.3.3.3.1. 方法有異常處理器

3.3.3.4. b

3.3.3.4.1. 在阻塞模式下發生的編譯

3.3.3.5. n

3.3.3.5.1. 原生方法封裝時發生的編譯

4. 分層編譯級別

4.1. 如果沒有額外的CPU周期可用,你能做的就是儘量縮減應用程式的大小

4.2. C1編譯器有3個級別,所有總共有5個編譯級別

4.2.1. 0

4.2.1.1. 解釋代碼

4.2.2. 1

4.2.2.1. 簡單C1編譯代碼

4.2.3. 2

4.2.3.1. 受限C1編譯代碼

4.2.4. 3

4.2.4.1. 完全C1編譯代碼

4.2.5. 4

4.2.5.1. C2編譯代碼

4.3. C1編譯器得到代碼是如何使用的信息之後,會利用這些信息進行優化,然後才開始編譯

4.4. 如果C2編譯器隊列已滿,那麼隊列中的方法會被取出,在級別2上編譯

4.5. 如果C1編譯器隊列已滿,那麼計劃在級別3上編譯的方法在等待編譯的同時,可以進行級別4的編譯

4.5.1. 它會被快速編譯到級別2,然後轉到級別4

4.6. 不重要的方法可以從級別2或者級別3開始編譯

4.6.1. 它們本質上不那麼重要,所以會回到級別1

4.7. 如果代碼發生了逆優化,就會回到級別0

5. 逆優化(deoptimization)

5.1. 編譯器不得不“撤銷”之前的編譯

5.1.1. JVM替換之前編譯的代碼的過程

5.2. 發生情況

5.2.1. 代碼被丟棄(made not entrant)

5.2.2. 產生僵屍代碼(made zombie)

5.3. 代碼被丟棄的原因

5.3.1. 類和介面的工作方式

5.3.1.1. 逆優化對性能並沒有太大影響

5.3.2. 分層編譯的工作方式

5.3.2.1. 當代碼被C2編譯器編譯時,JVM必須替換已經被C1編譯器編譯的代碼

5.3.2.2. 它將舊代碼標記為丟棄,並用逆優化機制替換為新編譯的(更高效的)代碼

5.3.2.3. 讓代碼變得更快

5.4. 逆優化僵屍代碼

5.4.1. 僵屍代碼的小規模重新編譯,不會對大多數應用程式產生顯著的影響


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 前端要不要學習設計模式 始終認為每個行業都有自己的特點,各自的專業性。一個開發工程師如果不知道電腦是哪些基本硬體組成,那麼我們大概率都會認為這個人非常不專業。那麼前端要不要學設計模式呢?設計模式跟前端有多大關係呢? 前端工程師首先是一個工程師,既然是一個軟體工程師,那麼類似設計模式、數據結構、網路相 ...
  • map、forEach、filter這三者都可以遍曆數組,他們之間有什麼區別呢? map():方法定義在JavaScript的Array中,它返回一個新的數組,數組中的元素為原始數組調用函數處理後的值值得註意的是: 1、map()函數不會對空數組進行檢測; 2、map()函數不會改變原始數組,它形成 ...
  • <!DOCTYPE html> <html> <head> <title>Get Video Frame Example</title> </head> <body> <div id="result"></div> <script> // 獲取視頻第一幀的函數 function getVideoFi ...
  • 今天早上打開電腦,更新了日常工作的github倉庫,然後就是習慣性地執行了"npm install",發現報了下麵這個錯誤: Error: error:0308010C:digital envelope routines::unsupported 順便看了一下錯誤堆棧,發現是一個Node的內核文件拋 ...
  • 在許久之前,曾經寫過這樣一篇文章 -- 不定寬溢出文本適配滾動。我們實現了這樣一種效果: 文本內容不超過容器寬度,正常展示 文本內容超過容器的情況,內容可以進行跑馬燈來回滾動展示 像是這樣: 但是,之前的方案,有一個很明顯的缺點,如果我們事先知道了容器的寬度,那麼沒問題,但是如果沒法確定容器的寬度, ...
  • 客戶端和伺服器 客戶端與伺服器的通信 互聯網:錯綜複雜的網路,比如每個快遞車走的路. TCP/IP:定義數據如何傳輸的通信協議,比如快遞的包裝,發貨規則. DNS:功能變數名稱系統伺服器,輸入一個網址時,找到網頁的伺服器,才能發送 HTTP 請求到正確的地方。(功能變數名稱->IP),比如發貨地址. HTTP:超文 ...
  • 一起來看看大道至簡的一些基本設計思想,首先我們來看一下什麼是封裝。 封裝:也叫做信息隱藏,或者數據訪問保護。放到程式上來講,就是隱藏類的屬性,還有實現細節,僅對外公開一些介面。那麼外部,就只能通過這個類暴露的這些訪問介面,按照這個類提供的方式來訪問類的內部信息或者數據。這樣子的一種情況就叫做封裝。 ...
  • 這篇文章主要討論分散式系統中的故障恢復和常用的故障檢測方法,包括固定心跳檢測和根據歷史心跳信息預測故障檢測方法。 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...