導航:首頁 > 編程語言 > java性能優化視頻

java性能優化視頻

發布時間:2024-11-26 15:04:54

1. java性能優化系列之-JIT即時編譯器與Java內存管理機制

JIT(即時編譯器)的目的在於提高熱點代碼的執行效率。在運行時,虛擬機會將這些代碼編譯成與本地平台相關的機器碼,並進行各種層次的優化。完成這一任務的編譯器被稱為即時編譯器(Just In Time Compiler),簡稱 JIT 編譯器。

即時編譯器不是虛擬機必需的部分,Java 虛擬機規范並沒有規定 Java 虛擬機內必須要有即時編譯器的存在,更沒有限定或指導即時編譯器應該如何去實現。但是,即時編譯器編譯性能的好壞、代碼優化程度的高低卻是衡量一款商用虛擬機優秀與否的最關鍵的指標之一。它也是虛擬機中最核心且最能體現虛擬機技術水平的部分。

目前主流的 HotSpot 虛擬機默認採用一個解釋器和其中一個編譯器直接配合的方式工作,程序使用哪個編譯器,取決於虛擬機運行的模式。在 HotSpot 中,解釋器和 JIT 即時編譯器是同時存在的,他們是 JVM 的兩個組件。對於不同類型的應用程序,用戶可以根據自身的特點和需求,靈活選擇是基於解釋器運行還是基於 JIT 編譯器運行。HotSpot 為用戶提供了幾種運行模式供選擇,可通過參數設定,分別為:解釋模式、編譯模式、混合模式,HotSpot 默認是混合模式,需要注意的是編譯模式並不是完全通過 JIT 進行編譯,只是優先採用編譯方式執行程序,但是解釋器仍然要在編譯無法進行的情況下介入執行過程。

位元組碼是指平常所了解的 .class 文件,Java 代碼通過 javac 命令編譯成位元組碼。機器碼和本地代碼都是指機器可以直接識別運行的代碼,也就是機器指令。位元組碼是不能直接運行的,需要經過 JVM 解釋或編譯成機器碼才能運行。Java 源碼轉換成位元組碼的過程是由 JVM 執行引擎來完成的。

JVM 的類載入是通過 ClassLoader 及其子類來完成的,類的層次關系和載入順序可以由下圖來描述。Bootstrap ClassLoader 負責載入 $JAVA_HOME 中 jre/lib/rt.jar 里所有的 class,由 C++ 實現,不是 ClassLoader 子類。Extension ClassLoader 負責載入 Java 平台中擴展功能的一些 jar 包,包括 $JAVA_HOME 中 jre/lib/*.jar 或 -Djava.ext.dirs 指定目錄下的 jar 包。App ClassLoader 負責記載 classpath 中指定的 jar 包及目錄中 class。Custom ClassLoader 屬於應用程序根據自身需要自定義的 ClassLoader,如 Tomcat、jboss 都會根據 J2EE 規范自行實現 ClassLoader。

JVM 是基於棧的體系結構來執行 class 位元組碼的。線程創建後,都會產生程序計數器(PC)和棧(Stack),程序計數器存放下一條要執行的指令在方法內的偏移量,棧中存放一個個棧幀,每個棧幀對應著每個方法的每次調用,而棧幀又是有局部變數區和操作數棧兩部分組成,局部變數區用於存放方法中的局部變數和參數,操作數棧中用於存放方法執行過程中產生的中間結果。

編譯器:把源程序的每一條語句都編譯成機器語言,並保存成二進制文件,這樣運行時計算機可以直接以機器語言來運行此程序,速度很快。解釋器:只在執行程序時,才一條一條的解釋成機器語言給計算機來執行,所以運行速度是不如編譯後的程序運行的快的。

Java 通過 javac 命令將 Java 程序的源代碼編譯成 Java 位元組碼,即我們常說的 class 文件。這是我們通常意義上理解的編譯。位元組碼並不是機器語言,要想讓機器能夠執行,還需要把位元組碼翻譯成機器指令。這個過程是 Java 虛擬機做的,這個過程也叫編譯。(實際上就是解釋,引入 JIT 之後也存在編譯)

Java 不完全是通過編譯來生成機器碼的,還結合了解釋執行,那如何判斷那些代碼是使用編譯執行還是解釋執行呢?定義:當虛擬機發現某個方法或代碼塊的運行特別頻繁時,就會把這些代碼認定為「熱點代碼」。

HotSpot 使用第二種 - 基於計數器的熱點探測方法。方法調用計數器觸發即時編譯的流程:計數器的種類(兩種共同協作)了解了熱點代碼和計數器有什麼用呢?即時編譯是需要達到某種條件才會觸發的。

解釋器與編譯器兩者各有優勢。解釋器:當程序需要迅速啟動和執行的時候,解釋器可以首先發揮作用,省去編譯的時間,立即執行。編譯器:在程序運行後,隨著時間的推移,編譯器逐漸發揮作用,把越來越多的代碼編譯成本地代碼之後,可以獲取更高的執行效率。

HotSpot 虛擬機啟用分層編譯的策略。分層編譯根據編譯器編譯、優化的規模與耗時,劃分出不同的編譯層次:實施分層編譯後,Client Compiler 和 Server Compiler 將會同時工作,許多代碼都可能會被多次編譯看,用 Client Compiler 獲取更高的編譯速度,用 Server Compiler 獲取更好的編譯質量,在解釋執行的時候也無須再承擔收集性能監控信息的任務。

Java程序員有一個共識,以編譯方式執行本地代碼比解釋方式更快,之所以有這樣的共識,除去虛擬機解釋執行位元組碼時額外消耗時間的原因外,還有一個很重要的原因就是虛擬機設計團隊幾乎把代碼的所有優化措施都集中在了即時編譯器之中,因此一般來說,即時編譯器生成的本地代碼比Javac產生的位元組碼更加優秀!

內聯優化是:一是去除方法調用的成本(如建立棧幀等),二是為了其他優化建立良好的基礎。方法的調用過程:(1) 首先會有個執行棧,存儲目前所有活躍的方法,以及它們的本地變數和參數;(2) 當一個新的方法被調用了,一個新的棧幀會被加到當前線程的棧頂,分配的本地變數和參數會存儲在這個棧幀中;(3) 跳到目標方法代碼執行;(4) 方法返回的時候,本地方法和參數會被銷毀,棧頂被移除;(5) 返回原來地址執行;

公共子表達式消除:如果一個表達式 E 已經計算過了,並且從先前的計算到現在 E 中所有變數的值都沒有發生變化,那麼 E 的這次出現就成為了公共子表達式!例如:int d = (c + b) * 12 + a + (a + b * c);

Java語言是一門動態安全的語言。如果有一個數組 foo[],在 Java 語言中訪問數組元素 foo[i] 的時候系統將會自動進行上下界的范圍檢查,即檢查 i 必須滿足 i >=0 && i < foo.length 這個條件,否則將拋出一個運行時異常:java.lang.。

逃逸分析的基本行為就是分析對象動態作用域:當一個對象在方法中被定以後,它可能被外部方法所引用,例如作為調用參數傳遞到其他方法中,稱為方法逃逸。甚至還有其可能被外部線程訪問到,譬如賦值給類變數或可以在其他線程中訪問的實例變數,稱為線程逃逸!

Java內存模型結構分為線程私有內存區:程序計數器、本地方法棧、虛擬機棧。線程共享內存區:Java 堆、方法區。對象實例化分析:這段代碼的執行會涉及 Java 棧、Java 堆、方法區三個最重要的內存區域。假設該語句出現在方法體中,obj 會作為引用類型(reference)的數據保存在 Java 棧的本地變數表中,在 Java 堆中保存該引用的實例化對象。

閱讀全文

與java性能優化視頻相關的資料

熱點內容
解壓成功的文件在哪裡找 瀏覽:391
抖音起號前期要關注哪些數據 瀏覽:699
怎麼讓網站適應手機 瀏覽:749
文件夾預覽pdf文件 瀏覽:544
pm硬碟分區工具win7破解 瀏覽:856
刪除數字文件夾找不到 瀏覽:518
Android50編碼程序截圖 瀏覽:809
creo20入門教程 瀏覽:392
網易雲草稿箱文件夾在哪裡 瀏覽:570
安徽夏米爾線切割編程軟體是什麼 瀏覽:509
win10能玩看門狗嗎 瀏覽:787
vb企業版是什麼app 瀏覽:730
linuxftp上傳文件許可權 瀏覽:818
哪個聽歌app不用流量 瀏覽:431
編程時如何設置刀補指令和刀補號 瀏覽:18
dvd文件怎樣轉存u盤 瀏覽:972
策劃旅遊線路app需要哪些點 瀏覽:28
samba設置文件夾許可權設置密碼 瀏覽:100
列印的pdf文件在哪裡查找 瀏覽:267
java性能優化視頻 瀏覽:931

友情鏈接