開始之前
JAVA平台已無處不在的Java EE的Java SE和Java ME和Java卡的Java的發展為無數程式員提供了工作機會,都是“Java”的,然而除了基本的Java的
- 不同平台的環境
的Java EE所啟動並執行硬體伺服器,作業系統,Java SE的所在PC機的體繫結構(X86/X64,MAC,SPARC等)和Java ME所啟動並執行手機或行動裝置的Java Card所在的智慧卡晶片類型等;
- 不同平台虛擬機器的特點
如是否支援多線程(這似乎是毋庸置疑,但是在Java卡平台上,由於計算資源相當有限,多線程目前還不被支援)的Java EE和Java SE的的虛擬機器特性幾乎相同,而Java ME的 CDC(串連裝置配置,連網裝置配置)和CLDC(有限串連裝置配置,連網受限裝置配置),更上傳者裝置和智慧卡的虛擬機器JCVM(Java卡 Java的文法集的裁剪;
- 不同平台的API和可用的第三方庫
的Java EE和Java SE的 的Java ME和Java卡與EE和SE是完全不同的,除了java.lang中。*,部分java.io. *等核心類庫保留外,其他的API和類庫完全不同。java.microedition *和javax。 microedition。表明這是ME平台,Java卡。表明這是Java卡平台。同時,由於EE和SE API和庫是不同平台程式員進階的必由之路。
從這個角度上說,Java的 JAVA EE和SE
回頁首
Java的虛擬機器
JAVA虛擬機器是支援的Java語言啟動並執行基礎,避開過多的JVM
圖1。Java的虛擬機器體繫結構
- 類裝載子系統通過類的全限定名(包名和類名,網路裝載還包括URL)將類裝載進運行時資料區;
- 方法區:類對於所有方法擴充功能和靜態 Java的位元組碼和待用資料;
- Java的堆:JAVA 記憶體不足的異常將會拋出,對Java的堆和垃圾收集的認識對應用效能調優很關鍵;
- 的Java棧:Java資源 JVM都是基於Java的棧的運行機制,而有一個例外的實現,Google行動裝置作業系統的Android的虛擬機器Dalvik的則是基於寄存器的機制(Dalvik的雖然支援的Java語言開發,但從虛擬機器的角度看,並不符合Java的標準),關於虛擬機器實現時,棧和寄存器機制的比較,請參考論文擴充功能“ 虛擬機器攤牌:堆棧對戰登記冊 “;
- 程式計數器:對於基於棧實現的JVM,這幾乎是唯一寄存器了,它用來指示當前的Java執行引擎執行到哪條的Java位元組碼,指標指向方法擴充功能區的位元組碼;
- 本地方法棧:這是Java的叫用作業系統本地庫的地方,用來實現JNI(Java本地介面的Java本地介面);
- 執行引擎:JVM的心臟,控制裝入Java的位元組碼並解析;
- 本地介面:串連了本地方法擴充功能棧和作業系統庫。
Java的位元組碼是JVM的指令,所有的Java平台虛擬機器有各自的指令集,而大部分指令相同,共200條左右,Java卡 JAVA程式員來說,是透明的。下面是一段Java的方法擴充功能的位元組碼樣本:
清單1。Java的位元組碼例
/ * 0x000092c4:0x04a7:* / _SCONST_0, / * 0x000092c5:0x04a8:* / _SCONST_0, / * 0x000092c6:0x04a9:* / _INVOKESTATIC,HIGH(0x08e8),LOW(0x08e8) / * 0x000092c9:0x04ac:* / _POP, / * 0x000092ca:0x04ad:* / _INVOKESTATIC,HIGH(0x8046),低(0x8046), / * 0x000092cd:0x04b0:* / _IFEQ,84, / * 0x000092cf:0x04b2:* / _INVOKESTATIC,HIGH(0x8044),低(0x8044), / * 0x000092d2:0x04b5:* / _GOTO,79, / * 0x000092d4:0x04b7 * / _ASTORE,7, |
當程式計數器中值為0x000092ca:0x04ad,表明下一條即將執行位元組碼為_INVOKESTATIC,HIGH(0x8046),低(0x8046),該位元組碼錶明將調用某個靜態方法。
Java的 Java的 程式所涉及的空間分配和回收包括:
- Java的堆建立的Java的
- Java的
來看一段位元組碼在Java的棧中的執行樣本,100與98相加:
清單2。整數加法運算的Java的位元組碼
iload_0 / /載入局部變數,整型,壓入棧中 iload_1 / /載入局部變數,整型,壓入棧中 IADD / /彈出兩個整型數,相加,將結果壓入棧 istore_2 / /彈出整型數,存入局部變數2 |
圖2。整數加法運算的Java棧行為
此外,對於JVM,還需瞭解支援的資料類型和。CL1佔用的空間:
圖3。Java的資料類型
回頁首
按代垃圾收集機制
雖然各家JVM的實現(星期日熱點,甲骨文JRockit,IBM J9
- 阿的活躍對象全部複製到空間B,然後一次性回收整個空間
- GC暫停時間,較大的掃描時間開銷,產生較多的空間片段;
代的劃分:
- 1個伊甸園區和2個存活區用來實施複製演算法;
- 年老代:從年輕代存活下來的對象被複製到年老代,主要實施標記清除或標記清除整理演算法;
- 的持久代:裝載的類資料和資訊儲存於此,無可消亡對象。
Java的虛擬機器都提供了相應的選項來設定各個代所佔用區的大小,無論是Java EE的的伺服器應用,還是Java SE的
垃圾收集按頻率可分為:
- 次收集(小集合):頻繁發生在年輕代,收集快速消亡的對象;
- 主收集(主要徵收):年輕代和年老代的全範圍收集,頻率很低。
垃圾收集運行時,同一個CPU上的所有其它線程都將會被阻塞,所以對於Java的 JVM實現的垃圾收集機制對多CPU
回頁首
設定虛擬機器參數
J9虛擬機器在IBM IBM的J9。
GC的策略進行有效最佳化。相關參數是-Xgcpolicy:optthruput | optavgpause | GENCON子池]
- Xgcpolicy:optthruput,針對有效產出最佳化,這是虛擬機器預設的GC
- Xgcpolicy:optavgpause,針對GC導致的停頓最佳化,通過並發地執行一部分垃圾收集,在高有效產出和短GC
- Xgcpolicy:GENCON,分代並發進行
- -Xgcpolicy:subpool,子池最佳化,採用與預設策略相似的演算法,但是採用一種比較適合多處理器電腦的分配策略。適用於在多核環境下啟動並執行具有較高對象建立速率的多線程應用。
除了 設定GC
回頁首
容易忽視的設計,編程原則和習慣
對虛擬機器工作機制的瞭解能夠使我們有把握寫出更優雅,更高效的Java的代碼。下面是幾條值得參考的設計,編程原則和習慣。
- 及時更新虛擬機器。
API,更好的實現最佳化。這一點對嵌入式的Java(的Java ME和Java的 EE和SE安裝的伺服器和PC VM的版本更新。
- 良好的物件導向設計和架構,應用設計模式。
這點對於Java的 API,看所需的功能是否已有現成的實現可供調用,虛擬機器平台實現的API大都具有良好的效能。
- 關心的Java棧。
前面瞭解到,對於基於棧的爪哇 Java的
- 加強對象管理,不放任自流。
JAVA程式員忽視,遺留的引用會導致GC無法回收這些邏輯上消亡的對象,看下面程式碼範例:
清單3。的Java實現的棧
公用類Stack { 私人靜態最終詮釋MAXLEN = 10; 私人對象STK [] =新的對象[MAXLEN]; 私人STKP = -1; 公用無效推動(對象p){ STK [+ + STKP] = P; } 公用對象POP1(){ 返回STK [STKP - ]; } 公用對象POP2(){ 對象p = STK [STKP]; STK [STKP - ] = NULL; 返回P; } } |
範例程式碼是一個棧結構,棧中儲存物件引用,容量為10,STKP是棧頂指標,推方法擴充功能將對象壓入棧中,POP1和POP2彈出棧頂對象。POP1
清單4。Java的對象池代碼
進口的java.util.HashMap; 進口java.util.LinkedHashSet; 公用類的ObjectFactory { / **一個計數器,用來在使用中的對象的數量進行計數。* / 私人靜態詮釋objInUse = 0; / **一個計數器,用來計數的對象池的數量。* / 私人靜態詮釋objInPool = 0; / **對象遊泳池。* / 私人靜態HashMap objectPool =新的HashMap(); / **一個特定的類對應的對象池。* / 私人靜態LinkedHashSet的subObjPool; / **用於產生對象* / 同步靜態對象產生的String className的{ 對象retObj = NULL; subObjPool中=(LinkedHashSet的)objectPool.get(類名); 如果(subObjPool!=的返回null && subObjPool.size()<0){ retObj = subObjPool.iterator()下(); subObjPool.remove(retObj); objInPool - ; } else { 嘗試{ retObj:= newObj(類名); }趕上(InstantiationException即){ 返回null; }趕上(IllegalAccessException IAE) 返回null; }的catch(ClassNotFoundException異常cnfe) 返回null; } } objInUse + +; 返回retObj; } 公用靜態無效的同步下降(對象freeObject){ (freeObject!= NULL){ subObjPool中=(LinkedHashSet的)objectPool.get(類名); 如果(subObjPool == NULL){ subObjPool =新LinkedHashSet的(); objectPool.put(類名subObjPool); } 如果(!subObjPool.contains(freeObject)){ subObjPool.add(freeObject); objInPool + +; objInUse - ; } } } / **現在都在使用中的對象的數目進行計數。* / 公用靜態詮釋countObjectInUse的(){ 返回objInUse; } / **檢查的對象池的當前大小。* / 公用靜態詮釋checkPoolSize的(){ 返回objInPool; } / **新的對象類的名稱。* / 私人靜態對象newObj的(字串類名) 拋出InstantiationException,IllegalAccessException, ClassNotFoundException異常{ 對象obj =調用Class.forName(類名)。的newInstance(); 返回obj的; } } |
回頁首
Java的事件探查器工具
Java的事件探查器是採用JMX(Java管理擴充,JAVA資源管理架構)或JVMPI(Java虛擬機器事件探查器介面,Java的虛擬機器監視程式介面)實現的對Java的虛擬機器中的資源,應用程式物件等進行監試的一類工具。探查 Java的 事件探查器工具是分析的Java程式效能的好幫手,但歸根結底,效能的提高還依賴於程式員對Java的虛擬機器有一定瞭解,在此基礎上遵循良好的設計和開發原則。這也是Java的程式員成為真正高手的必由之路。
關於如何流量分析器工具,讀者可參考相關資源進行深入研究,常用的Java的事件探查器工具有:
- JConsole中,虛擬機器SDK內建工具,安裝好Java的SDK後,在/ bin中目錄下啟動;
- 的Eclipse測試與效能工具平台(TPTP)是由Eclipse.org的頂級項目提供的一個測試與效能監測方面的工具外掛程式;
- 孫NetBeans Profiler將內建於Netbeans的中探查器,方便用Netbeans的開發時使用;
- 視覺VM,最初,孫隨JDK 6 Update 7的發布的分析器,視覺虛擬機器包含JConsole的,同時資源分類介面更加美觀且便於使用。
回頁首
結束語
本文從Java的虛擬機器的視角出發,剖析了與Java的 JAVA程式員提高效能最佳化意識和水平有所協助。
參考資料
學習
- 閱讀的Sun關於Java的調優的白皮書。
- 閱讀的Sun Java虛擬機器熱點體繫結構白皮書。
- 瞭解和深入學習即時的Java技術。
- 查看IBM JDK分析與診斷相關文章。
- 瞭解IBM實現的的Java虛擬機器的垃圾收集器。
- 從開源的Java事件探查器工具列表瞭解更多開源分析器工具。
- 瞭解JVMPI技術。
- 到視覺VM首頁瞭解的Visual VM。
- developerWorks的Java技術專區:尋找數百篇有關Java的編程各方面的文章。
獲得產品和技術
- 下載IBM軟體試用版,體驗強大的DB2,易初蓮花時,Rational,的Tivoli和的WebSphere軟體。
討論
- 查看的developerWorks的部落格的最新資訊。