溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Java HotSpot性能引擎的體系結(jié)構(gòu)有哪些知識點

發(fā)布時間:2022-01-07 20:22:53 來源:億速云 閱讀:126 作者:iii 欄目:編程語言

本篇內(nèi)容介紹了“Java HotSpot性能引擎的體系結(jié)構(gòu)有哪些知識點”的有關(guān)知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

1. 引言

Java>TM平臺正在成為軟件開發(fā)和部署的主流載體。在許多領(lǐng)域,Java平臺的使用率正在迅猛增長--從信用卡到大型計算機(jī)、從網(wǎng)頁applets到大型商務(wù)應(yīng)用程序。因此,Java技術(shù)的品質(zhì)、成熟度和性能就成了對每一個開發(fā)人員和用戶至關(guān)重要的因素。Sun Microsystems,Inc.正在重點投資于能夠在許多處理器和操作系統(tǒng)面前"抬起擋路的欄桿"的技術(shù),應(yīng)用這種技術(shù),軟件開發(fā)人員可以將基于Java的應(yīng)用程序,在不考慮處理器和操作系統(tǒng)的情況下有效而可靠地運行。

人們對Java平臺感興趣的一個主要原因是:基于Java技術(shù)的程序與用傳統(tǒng)語言編寫的程序不同,它們是以一種可移植的和安全的形式而分布的。過去,使用可移植的分布形式一般來說都意味著在程序執(zhí)行中的性能要下降。通過采用現(xiàn)代動態(tài)編譯技術(shù),這種性能的下降得以減緩,其本質(zhì)可說是"雙收其利"。

舉一個簡單但很重要的例子:我們可以使一個Java技術(shù)編譯器為特定版本的處理器"在運行中"生成優(yōu)化的機(jī)器碼(例如,盡管奔騰和奔騰II處理器可以運行相同的機(jī)器碼,但沒有一種形式的機(jī)器碼可以同時對上述二者都是優(yōu)化的)。于是,Java編程語言的字節(jié)碼分布形式不僅可以提供移植性,而且實際上還可以為性能的提高提供新的機(jī)會。

本文將介紹Java的第二代性能技術(shù)--Java HotSpot性能引擎。Java HotSpot性能引擎幾乎在其設(shè)計的每一個領(lǐng)域都有創(chuàng)新,它使用了廣泛的可用來提高性能的技術(shù);這包括可檢測并加速性能關(guān)鍵性(performance-critical)代碼"在運行中"的適配性優(yōu)化技術(shù)。Java HotSpot還提供了超快速(ultra-fast)線程同步,以獲取線程安全的基于Java技術(shù)的程序的最大性能;它還提供了垃圾回收器(GC),GC不僅特別快,而且是完全"精確"的(因而也更可靠);另外,采用最新技術(shù)的算法也減少或消除了用戶對垃圾回收而引起的暫停的感覺。最后,由于Java HotSpot性能引擎在源代碼級是以一種簡潔、高級的面向?qū)ο蟮脑O(shè)計風(fēng)格編寫的,因而還進(jìn)一步改善了維護(hù)性和擴(kuò)展性。

2. 概述

下面是Java HotSpot性能引擎的主要結(jié)構(gòu)性優(yōu)勢:

1) 更好的一般性能

  • 無句柄對象(為提高速度,對象的引用被實現(xiàn)為直接指針);

  • 更快的Java編程語言的線程同步;

  • 為達(dá)到更快的C代碼的調(diào)出和調(diào)入,C和Java代碼可共享相同的激活棧;

  • 與及時編譯JIT相比較,大大減小了代碼空間和啟動時間總開銷。

2) 最利于繁殖的(best-of-breed)性能

  • 為獲得真本地代碼性能,優(yōu)化了本地代碼編譯器;

  • 適配性的"熱點(Hot Spot)"檢測主要集中于性能-關(guān)鍵性代碼的優(yōu)化上,從而大大減少了總編譯時間和對已編譯代碼的內(nèi)存需求;

  • 方法內(nèi)嵌技術(shù)為大部分程序消除了大多數(shù)動態(tài)方法調(diào)用;

  • 對非內(nèi)嵌方法的更快的方法調(diào)用。

3) 精確的、相繼的(generational)復(fù)制垃圾回收器

  • 更快的對象分配;

  • 精確性提供了更準(zhǔn)確的對象回收(與保守的(conservative)或半精確的(partially-accurate)那種可引起難以預(yù)料的內(nèi)存泄漏的回收器不同);

  • 相繼回收對大多數(shù)程序來說極大地提高了回收效率;

  • 對大多數(shù)程序來說, 相繼回收還極大地減小了回收"舊的對象"而引起暫停所出現(xiàn)的頻率;

  • 相繼回收也為使用大量"活的(live)"對象的內(nèi)存的應(yīng)用程序極大地改善了性能擴(kuò)展性;

  • 使用標(biāo)記-整理(mark-compact)算法來回收"舊的"對象,消除了內(nèi)存碎 片,增加了本地性(locality);

  • 增量"無暫停"垃圾回收器為"長壽"對象、甚至為極大量的"活"的對象在實質(zhì)上消除了對象回收過程中出現(xiàn)的用戶可視的暫停,這對等待時間敏感的應(yīng)用程序(如服務(wù)器)以及大數(shù)據(jù)量的程序來說是理想的;

4) 先進(jìn)的高級設(shè)計

  • 透明調(diào)試和簡檔(profiling)語意--Java HotSpot體系結(jié)構(gòu)能夠使本地代碼的生成及優(yōu)化對程序員完全透明,它可以按照純字節(jié)碼語意提供全部簡檔和調(diào)試信息,而不管內(nèi)部實際上所用的優(yōu)化方法。

3. 體系結(jié)構(gòu) Java HotSpot性能引擎的體系結(jié)構(gòu)使多年來在Sun Microsystems的實驗室里所做的研究達(dá)到了頂點。它綜合采用了具有最新技術(shù)水平的內(nèi)存模型、垃圾回收器和適配性優(yōu)化器;并且它是以一種特別高級的和面向?qū)ο蟮娘L(fēng)格寫成的。

以下部分將介紹Java HotSpot性能引擎的重要的體系結(jié)構(gòu)及其特性。

4. 內(nèi)存模型

4.1 無句柄對象

Java 2 軟件開發(fā)工具包(SDK)使用間接句柄來表示對象的引用。雖然在垃圾回收過程中,這樣做會使對象的重新定位變得更加簡單,但這會引發(fā)一個重要的性能瓶頸,因為大多數(shù)對Java編程語言對象的實例變量的訪問都需要兩個層次的間接引用。Java HotSpot性能引擎消除了句柄的概念:對象的引用被實現(xiàn)為直接指針,從而可提供對實例變量的C-速度訪問。垃圾回收器則負(fù)責(zé)在內(nèi)存被回收過程中,當(dāng)對象被重新定位時,尋找并更新所有對在適當(dāng)位置上的對象的引用。

4.2 雙字(Tow-word)對象頭

Java HotSpot性能引擎使用雙機(jī)器-字對象頭,而不是象Java 2 SDK那樣使用三字對象頭。由于平均的Java編程語言的對象尺寸較小,因而這種技術(shù)對節(jié)省空間產(chǎn)生了重要作用(大約節(jié)省了8%的堆的大?。5谝粋€對象頭的字包含了身份標(biāo)識哈希碼和GC狀態(tài)等信息;第二個對象頭的字是一個對對象的類的引用。只有數(shù)組才有第三個對象頭字段,它是用來表示數(shù)組大小的。

4.3 將映射數(shù)據(jù)表示為對象

類、方法以及其它內(nèi)部映射數(shù)據(jù)被直接表示為堆上的對象(盡管這些對象也許不能被基于Java技術(shù)的程序所直接訪問)。這不僅簡化了內(nèi)存模型,而且使你可以采用與回收其它Java編程語言對象相同的垃圾回收器來回收這類映射數(shù)據(jù)。

4.4 本地線程支持,包括任務(wù)搶先和多重處理技術(shù)

每個線程方法的激活棧是使用宿主操作系統(tǒng)的線程模型來表示的。Java編程語言方法和本地方法可共享相同的棧,從而可允許在C和Java編程語言間的快速調(diào)用。使用宿主操作系統(tǒng)的線程調(diào)度機(jī)制可支持全搶先的Java編程語言線程。

使用本地操作系統(tǒng)的線程和調(diào)度機(jī)制的一個主要優(yōu)點是,它能夠透明地利用本地操作系統(tǒng)支持多重處理。由于Java HotSpot性能引擎被設(shè)計為對在執(zhí)行Java編程語言代碼時的搶先和/或多重處理引起的競爭狀態(tài)是不敏感的,因而Java編程語言線程將自動利用由本地操作系統(tǒng)所提供的任意調(diào)度機(jī)制和處理器分配策略。

5. 內(nèi)存垃圾回收

5.1 背景說明

Java編程語言對程序員的一個主要魅力在于,它是第一個可提供內(nèi)置自動內(nèi)存管理(或內(nèi)存垃圾回收)的主流編程語言。在傳統(tǒng)語言中,一般都使用顯式分配/釋放模型來進(jìn)行動態(tài)內(nèi)存分配。事實證明, 這不僅是造成內(nèi)存泄漏、程序錯誤以及用傳統(tǒng)語言編寫的程序崩潰的最主要原因之一,而且還是提高性能的瓶頸, 并且是形成模塊化和可再使用代碼的主要障礙(如果沒有顯式和難以理解的模塊間的協(xié)同操作,在模塊界限間確定釋放點有時幾乎是不可能的)。在Java編程語言中,垃圾回收也是支持安全性模型所必需的所謂"安全地"執(zhí)行這一語義的重要組成部分。

當(dāng)一個垃圾回收器能夠"證明"某個對象對正在運行的程序來說是不可訪問的時候,它僅通過回收該對象就可自動地在后臺處理對該對象的內(nèi)存的"釋放"。這種自動的處理過程不僅完全消除了由于釋放太少而引起的內(nèi)存泄漏,同時也消除了由于釋放太多而引起的程序崩潰和難以發(fā)現(xiàn)的引用錯誤。

從傳統(tǒng)上講,相對于顯式釋放模型來說, 垃圾回收一直被認(rèn)為是一種沒有效率且會引起性能下降的處理過程。事實上,使用現(xiàn)代垃圾回收技術(shù),可大大改善性能,且這種性能實際上要比由顯式釋放所提供的性能好得多。

5.2 Java HotSpot垃圾回收器

Java HotSpot性能引擎具有一個先進(jìn)的垃圾回收器,它除了包含以下將要描述的先進(jìn)技術(shù)特性外,還充分利用了簡潔和面向?qū)ο蟮脑O(shè)計優(yōu)勢,提供了一個高層次的垃圾收集結(jié)構(gòu)框架,這個框架可被輕松地配置、使用或擴(kuò)展以使用新的回收算法。

以下將介紹Java HotSpot垃圾回收器的的主要特性。總體來講,所用各種技術(shù)的綜合結(jié)果無論是對需要盡可能高的性能的應(yīng)用程序來說,還是對不期望有由于碎片而引起內(nèi)存泄漏和內(nèi)存不可訪問的長時運行應(yīng)用程序來說,都是較好的。Java HotSpot性能引擎不僅能夠提供具有最新技術(shù)水平的垃圾回收器性能,而且可以保證全部內(nèi)存回收,并完全消除內(nèi)存碎片。

5.3 精確性

Java HotSpot垃圾回收器是一種全精確回收器, 與之形成對比的是, 許多垃圾回收器都是保守的(conservative)或半精確的(partially-accurate)。雖然保守的垃圾回收由于易于增加到一個不支持垃圾回收的系統(tǒng)中, 因而具有一定的吸引力, 但它卻有一定的缺陷。

一個保守的垃圾回收器不能確切地斷定所有對象的引用的分布位置, 其結(jié)果是, 它必須保守地假設(shè)那些看似要引用一個對象的內(nèi)存字(memory word)是事實上的對象引用。這就意味著它可能導(dǎo)致某種錯誤, 例如將一個整數(shù)誤認(rèn)為是一個對象指針; 這會造成一些負(fù)面影響。首先, 當(dāng)發(fā)生這樣的錯誤時(實際并不普遍), 內(nèi)存泄漏會不可預(yù)知地以一種對應(yīng)用程序員來說實質(zhì)上不可再生(reproduce)或調(diào)試(debug)的方式出現(xiàn)(盡管由虛懸(dangling)對象引用所引起的崩潰仍可被預(yù)防, 并且如果有足夠的備份內(nèi)存, 該程序仍可正確執(zhí)行);第二, 由于它可能已經(jīng)導(dǎo)致了某個錯誤, 因而一個保守的回收器必須使用句柄來間接引用對象(降低性能), 或者避免重新定位對象;因為重新定位無句柄對象需要更新所有對對象的引用, 這在回收器不能確切地斷定一個表面上的引用就是一個真的引用時, 是不可能做到的。不能重新定位對象將會導(dǎo)致對象內(nèi)存碎片, 且更重要的是, 它會妨礙使用以下描述的先進(jìn)的相繼復(fù)制回收算法。

因為Java HotSpot回收器是全精確的, 因而它可以提供幾個有力的設(shè)計保證, 這在保守的回收器上是不可能提供的: · 所有不可訪問的對象內(nèi)存都可以被可靠地回收;

· 所有對象都可以被重新定位, 因而可對對象內(nèi)存的進(jìn)行整理;這就消除了對象內(nèi)存的碎片并增加了內(nèi)存的本地性。

5.4 相繼的復(fù)制回收

Java HotSpot性能引擎采用了具有先進(jìn)技術(shù)的相繼復(fù)制回收器,它有兩個主要優(yōu)點:

· 與Java 2 SDK相比,為大部分程序較大地提高了分配速度和總的垃圾回收效率(通常提高了5倍);

· 相應(yīng)地減小了用戶可感覺的垃圾回收時的"暫停"所出現(xiàn)的頻率。

相繼回收器利用了在大部分程序中大多數(shù)對象(通常為95%)都是非常短命的也就是被用作臨時數(shù)據(jù)結(jié)構(gòu)這樣一個事實,通過將新創(chuàng)建的對象隔離到一個對象"幼稚園(nursery)"中,一個相繼回收器可以完成以下幾件事:第一,因為在對象幼稚園中,新的對象就象堆棧那樣被一個接一個地分配,因而分配變得特別的快,因為這樣它僅涉及單個指針的更新及對幼稚園溢出的單個檢查。第二,到幼稚園溢出時,大部分幼稚園中的對象已經(jīng)"死了",這就使垃圾回收器可以只簡單地將幼稚園中極少數(shù)存活的對象移到別處就可以了,從而不必對幼稚園中死去的對象做回收工作。

5.5 采用標(biāo)記-整理算法的"舊對象"回收器

盡管相繼的復(fù)制回收器可以有效地回收大部分死的對象,但較長壽命的對象仍然在"舊對象"內(nèi)存區(qū)不斷地堆積。從內(nèi)存不足狀態(tài)或程序要求的角度考慮,有時必須執(zhí)行對舊對象的垃圾回收。Java HotSpot性能引擎可以使用一種標(biāo)準(zhǔn)的標(biāo)記-整理回收算法,它從"根"開始遍歷活對象的全部圖解,然后掃描內(nèi)存并整理回收由死的對象遺留的縫隙。通過整理回收堆中的縫隙(而不是將它們回收到一個釋放清單中),可消除內(nèi)存碎片;由于消除了釋放清單搜索,則舊對象的分配將是更合理的。

5.6 增量"無暫停"垃圾回收器

標(biāo)記-整理回收器不能消除所有用戶可感覺的暫停, 用戶可感覺的垃圾回收暫停是在 "舊的"對象(在機(jī)器術(shù)語中指已經(jīng) "活" 了一段時間的對象)需要做垃圾收集時出現(xiàn)的, 而且這種暫停與現(xiàn)存的活的對象的數(shù)據(jù)量成比例。這就意味著當(dāng)有較多數(shù)據(jù)被處理時, 該暫??赡苁侨我獯蟮? 這對服務(wù)器應(yīng)用程序、動畫或其它軟實時應(yīng)用程序來說,是一種非常不好的的表現(xiàn)。

Java HotSpot性能引擎提供了另一種使用的舊空間垃圾回收器以解決這一問題。該回收器是全增量的, 它消除了用戶可探察的垃圾回收暫停。該增量回收器可平滑地按比例增加,即使在處理特大的對象數(shù)據(jù)集時,也可以提供相對不變的暫停時間。這為如下應(yīng)用程序創(chuàng)造了極佳的表現(xiàn):

  • 服務(wù)器應(yīng)用程序, 特別是高可用性的應(yīng)用程序;

  • 處理非常大的 "活的"對象的數(shù)據(jù)集的應(yīng)用程序;

  • 不期望有用戶可注意到的暫停的應(yīng)用程序, 如游戲、動畫或其它高交互性的應(yīng)用程序。

無暫?;厥掌鞑捎玫氖且环N增量舊空間回收方案, 學(xué)術(shù)上稱該方案為"列車(train)"算法。該算法是將舊空間回收時的暫停分離為許多微小的暫停(典型的暫停小于10毫秒), 然后將這些微小的暫停隨著時間散布開來, 于是, 實際上的程序?qū)τ脩魜碇v,就象是沒有暫停一樣。由于列車算法不是一個硬實時(hard-real time)算法, 因而它不能保證暫停次數(shù)的上限。然而, 實際上特大量的暫停是極罕見的, 并且它們不是由大的數(shù)據(jù)集直接引起的。

作為一種人們十分歡迎的有益的副產(chǎn)品, 無暫?;厥者€可以改善內(nèi)存本地性。因為該算法試圖將緊密 "耦合的(coupled)"對象組重新定位到相鄰的內(nèi)存區(qū)域中, 從而可以為這些對象提供最好的內(nèi)存分頁和高速緩存本地性之屬性。這對操作不同的對象數(shù)據(jù)集的多線程應(yīng)用程序來說, 也是非常有益的。 6. 超快速線程同步

Java 編程語言的另一個重要的誘人之處,是它提供了一種語言級的線程同步。這就使得編寫帶有精細(xì)的線程同步加鎖的多線程程序變得十分簡單。然而不幸的是,目前的同步實現(xiàn)相對于其它Java編程語言中的微操作來說,效率非常底,它使精細(xì)的同步的操作變成了性能主要的瓶頸。

Java HotSpot性能引擎在線程的同步實現(xiàn)上取得了突破,它極大地促進(jìn)了同步性能的提高。其結(jié)果是使同步性能變得如此之快,以至于對大多數(shù)現(xiàn)實世界的程序來說,它已經(jīng)不是一個重要的性能問題了。

除了在"內(nèi)存模型"一節(jié)中提到的在空間方面的益處之外,同步機(jī)制通過為所有無競爭的同步(它動態(tài)地由絕大多數(shù)同步所構(gòu)成)提供超快速和常數(shù)-時間(constant-time)性能, 從而也提供了它的在性能方面的益處。

Java HotSpot同步實現(xiàn)完全適合于多重處理并應(yīng)該展示出色的多處理器性能特征。

7. Java HotSpot編譯器

7.1 背景說明

Java編程語言是一種新的具有獨特性能特征的編程語言。迄今為止,大部分試圖提高其性能的嘗試都集中在如何應(yīng)用為傳統(tǒng)語言開發(fā)的編譯技術(shù)上。及時編譯器是基本的快速傳統(tǒng)編譯器,它可以"在運行中"將Java字節(jié)碼轉(zhuǎn)換為本地機(jī)器代碼。及時編譯器在終端用戶的實際執(zhí)行字節(jié)碼的機(jī)器上運行,并編譯每一個被首次執(zhí)行的方法。

在JIT編譯中存在著幾個問題。首先,由于編譯器是在"用戶時間"內(nèi)運行于執(zhí)行字節(jié)碼的機(jī)器上,因此它將受到編譯速度的嚴(yán)格限制:如果編譯速度不是特別快,則用戶將會感到在程序的啟動或某一部分的明顯的延遲。這就不得不采取一種折衷方案,用這種折衷方案將很難進(jìn)行最好的優(yōu)化,從而將會大大地降低編譯性能。

其次,即使JIT有時間進(jìn)行全優(yōu)化,這樣的優(yōu)化對Java編程語言來說,也比對傳統(tǒng)語言(如C和C++)的優(yōu)化效果要差。這有以下幾個原因:

  • Java編程語言是動態(tài)"安全的",其含義是保證程序不違反語言的語義或直接訪問非結(jié)構(gòu)化內(nèi)存。這就意味著必須經(jīng)常進(jìn)行動態(tài)類型測試, 例如,當(dāng)轉(zhuǎn)型時(casting)和向?qū)ο髷?shù)組進(jìn)行存儲時。

  • Java編程語言在"堆(heap)"上對所有對象進(jìn)行分配,而在C++中,許多對象是在棧(stack)上分配的。這就意味著Java編程語言的對象分配效率比C++的對象分配效率要高得多。除此之外,由于Java編程語言是垃圾回收式的,因而它比C++有更多的不同類型的內(nèi)存分配開銷(包括潛在的垃圾清理 (scavenging)和編寫-隔離(write-barrier)開銷)。

  • 在Java編程語言中,大部分方法調(diào)用是"虛擬的"(潛在是多態(tài)的),這在C++中很少見。這不僅意味著方法調(diào)用的性能更重要,而且意味著更難以為方法調(diào)用而執(zhí)行靜態(tài)編譯器優(yōu)化(特別是象內(nèi)嵌方法(inlining)那樣的全局優(yōu)化)。大多數(shù)傳統(tǒng)優(yōu)化在調(diào)用之間是最有效的,而Java編程語言中的減小的調(diào)用間距離可大大降低這種優(yōu)化的效率,這是因為它們使用了較小的代碼段的緣故。

  • 基于Java技術(shù)的程序由于其強(qiáng)大的動態(tài)類裝載的能力,因而可"在運行中"發(fā)生改變。這就使得它特別難于進(jìn)行許多類型的全局優(yōu)化,因為編譯器不僅必須能夠檢測這些優(yōu)化何時會由于動態(tài)裝載而無效,而且還必須能夠在程序執(zhí)行過程中解除和/或重做這些優(yōu)化,且不會以任何形式損壞或影響基于Java技術(shù)的程序的執(zhí)行語義(即使這些優(yōu)化涉及棧上的活動方法)。

上述問題的結(jié)果是使得任何試圖獲取Java編程語言的先進(jìn)性能的嘗試,都必須尋求一種非傳統(tǒng)的解決方案,而不是盲目地應(yīng)用傳統(tǒng)編譯器技術(shù)。

Java HotSpot性能引擎的體系結(jié)構(gòu)通過使用適配性的優(yōu)化技術(shù),解決了以上所提出的Java編程語言的性能問題。適配性的優(yōu)化技術(shù)是Sun公司的研究機(jī)構(gòu)Self小組多年以來在面向?qū)ο蟮恼Z言實現(xiàn)上的研究成果。

7.2 熱點Hot Spot檢測

適配性的優(yōu)化技術(shù)利用了大多數(shù)程序的有趣的屬性,解決了JIT編譯問題。實際上,所有程序都是花費了它們的大部分時間而執(zhí)行了它們中的很小一部分代碼。Java HotSpot性能引擎不是在程序一啟動時就對整個程序進(jìn)行編譯,而是在程序一啟動時就立即使用解釋器(interpreter)運行該程序,在運行中對該程序進(jìn)行分析以檢測程序中的關(guān)鍵性"熱點(Hot Spot)",然后,再將全局本地碼(native-code)優(yōu)化器集中在這些熱點上。通過避免編譯(大部分程序的)不常執(zhí)行的代碼,Java HotSpot編譯器將更多的注意集中于程序的性能關(guān)鍵性部分,因而不必增加總的編譯時間。這種動態(tài)監(jiān)測隨著程序的運行而不斷進(jìn)行,因而,它可以精確地"在運行中"調(diào)整它的性能以適應(yīng)用戶的需要。

這種方法的一個巧妙而重要的益處是,通過將編譯延遲到代碼已被執(zhí)行一會兒之后("一會兒"是指機(jī)器時間,而不是用戶時間!),從而可在代碼被使用的過程中收集信息,并使用這些信息進(jìn)行更智能的優(yōu)化。除收集程序中的熱點信息外,也收集其它類型的信息,如與"虛擬"方法調(diào)用有關(guān)的調(diào)用者-被調(diào)用者的關(guān)系數(shù)據(jù)等。

7.3 方法內(nèi)嵌

正象在"背景說明"中所提到的,Java編程語言中的"虛擬"方法調(diào)用的出現(xiàn)頻率,是一個重要的妨礙優(yōu)化的瓶頸。當(dāng)Java HotSpot適配性優(yōu)化器在執(zhí)行過程中,一旦回收了有關(guān)程序"熱點"的信息后,它不僅能將這些"熱點"編譯為本地代碼,而且還可以執(zhí)行內(nèi)嵌在這些代碼上的大量的方法。

內(nèi)嵌具有重要的益處。它極大地減小了方法調(diào)用的動態(tài)頻率,這就節(jié)省了執(zhí)行這些方法調(diào)用所需要的時間。而更重要的是,內(nèi)嵌為優(yōu)化器生成了大得多的代碼塊。這種狀態(tài)可以大大地提高傳統(tǒng)編譯器的優(yōu)化技術(shù)的效率,從而消除提高Java編程語言性能的障礙。

內(nèi)嵌對其它代碼的優(yōu)化起到了促進(jìn)作用,它使優(yōu)化的效率大大提高。隨著Java HotSpot編譯器的進(jìn)一步成熟,操作更大的內(nèi)嵌代碼塊的能力將使實現(xiàn)更先進(jìn)的優(yōu)化技術(shù)成為可能。

7.4 動態(tài)逆優(yōu)化

盡管上述內(nèi)嵌是一種非常重要的優(yōu)化方法,但對于象Java編程語言那樣的動態(tài)的面向?qū)ο蟮木幊陶Z言來說,這在傳統(tǒng)上一直是非常難以實現(xiàn)的。此外,盡管檢測"熱點"和內(nèi)嵌它們所調(diào)用的方法已經(jīng)十分困難,但它仍然還不足以提供全部的Java編程語言的語義。這是因為,用Java編程語言編寫的程序不僅能夠"在運行中"改變方法調(diào)用的模式,而且能夠為一個運行的程序動態(tài)地裝載新的Java代碼。

內(nèi)嵌是基于全局分析的,動態(tài)裝載使內(nèi)嵌更加復(fù)雜了,因為它改變了一個程序內(nèi)部的全局關(guān)系。一個新的類可能包含了需要被內(nèi)嵌在適當(dāng)位置的新的方法。所以,Java HotSpot性能引擎必須能夠動態(tài)地逆優(yōu)化(如果需要,然后再重新優(yōu)化)先前已經(jīng)優(yōu)化過的"熱點",甚至在"熱點"代碼的執(zhí)行過程中進(jìn)行這種操作。沒有這種能力,一般的內(nèi)嵌將不能在基于Java的程序上安全地執(zhí)行。

7.5 優(yōu)化編譯器

只有性能關(guān)鍵性代碼才被編譯,這就"購買了時間",并可將這些時間用于更好的優(yōu)化。Java HotSpot性能引擎使用全優(yōu)化編譯器,以此替代了相對簡單的JIT編譯器。全優(yōu)化編譯器可執(zhí)行所有第一流的優(yōu)化。例如:死代碼刪除、循環(huán)非變量的提升、普通子表達(dá)式刪除和連續(xù)不斷的傳送(constant propagation)等。它還賦予優(yōu)化某些特定于Java技術(shù)的性能。如:空-檢查(null-check)和值域-檢查(range-check)刪除等。寄存器分配程序(register allocator)是一個用顏色表示分配程序的全局圖形,它充分利用了大的寄存器集(register sets)。Java HotSpot性能引擎的全優(yōu)化編譯器的移植性能很強(qiáng),它依賴相對較小的機(jī)器描述文件來描述目標(biāo)硬件的各個方面。盡管編譯器采用了較慢的JIT標(biāo)準(zhǔn),但它仍然比傳統(tǒng)的優(yōu)化編譯器要快得多。而且,改善的代碼質(zhì)量也是對由于減少已編譯代碼的執(zhí)行次數(shù)而節(jié)省的時間的一種"回報"。

7.6 小結(jié)

綜上所述,我們可以對Java HotSpot適配性優(yōu)化器的作用做如下小結(jié):

  • 一般來說,程序啟動得更快。這是因為,與JIT編譯器相比,預(yù)先編譯做得較少的緣故。

  • 編譯過程隨著時間展開,從而使編譯暫停時間更短,更不被用戶所注意。

  • 僅編譯性能關(guān)鍵性代碼的做法"購買了時間",從而可將這些時間用在執(zhí)行更好的優(yōu)化上。

  • 由于編譯較少的代碼, 編譯代碼所需的內(nèi)存較少.

  • 通過使編譯代碼前的等待時間變得長一點,可收集信息以執(zhí)行更好的優(yōu)化,如內(nèi)嵌,這種技術(shù)將具有深遠(yuǎn)的意義。

  • 通過高度優(yōu)化性能關(guān)鍵性代碼,使重要的代碼的運行速度更快。

7.7 對軟件可重用性(reusability)的影響

面向?qū)ο蟮木幊陶Z言的一個主要優(yōu)勢是,通過為軟件的重復(fù)使用提供一種強(qiáng)大的語言機(jī)制,來增加開發(fā)的生產(chǎn)力。然而實際上,很少能夠獲得這種可重用性。因為大量地使用這些機(jī)制可能會極大地減損性能,因而程序員都必須謹(jǐn)慎地使用它們。Java HotSpot技術(shù)的一個驚人的副作用是,它大大地減少了這種性能的減損代價。我們相信,這將會對面向?qū)ο蟮能浖拈_發(fā)方法產(chǎn)生重要的影響,它將第一次允許各個公司可以充分地使用面向?qū)ο蟮目芍赜眯詸C(jī)制,且不會減損他們的軟件性能。

這種作用的示例很容易獲得。一個對使用Java編程語言的程序員的調(diào)查結(jié)果將會明確表明,許多程序員都避免使用全"虛擬"方法同時也避免編寫較大的方法。因為他們確信,每一個虛擬方法的調(diào)用都會導(dǎo)致性能的下降。同時,"虛擬"方法(也就是在Java編程語言中的非"static"或"final"那些方法)的精細(xì)使用對高可重用性的類的構(gòu)造特別重要,因為每一個這樣的方法的作用就象一個"異常分支(hook)",它允許新的子類修改超類的操作。

由于Java HotSpot性能引擎可自動地內(nèi)嵌大部分虛擬方法調(diào)用,因此,性能下降的程度被大大地減小了,甚至在許多情況下,被全部消除了。

無論怎樣強(qiáng)調(diào)這種作用的重要性都不會過分。因為使用重要的可重用性機(jī)制,可以大大地改變有關(guān)性能的權(quán)衡關(guān)系, 這種技術(shù)具有從根本上改變面向?qū)ο蟮拇a的編寫方式的潛力。除此之外,隨著面向?qū)ο蟮木幊谭椒ǖ某墒欤幸环N明顯的向著更細(xì)分的對象以及更細(xì)分的方法發(fā)展的趨勢。這兩個趨勢都旨在以將來的代碼風(fēng)格,極力增加虛擬方法調(diào)用的頻率。隨著這種高級代碼風(fēng)格的流行,Java HotSpot技術(shù)的優(yōu)勢將愈發(fā)明顯。

8. Java本地接口(JNI)支持

Java HotSpot性能引擎可用標(biāo)準(zhǔn)Java本地接口(JNI)支持本地方法。以前用JNI編寫的本地方法在源代碼和二進(jìn)制代碼格式上都是向上兼容的。初始本地方法接口將不被支持(JNI被部分地引入,因為舊的接口沒有提供對本地方法DLLs的二進(jìn)制兼容性)。

“Java HotSpot性能引擎的體系結(jié)構(gòu)有哪些知識點”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實用文章!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI