新的JavaTM 虛擬機(VMs)具有能夠提高性能的特點, 並且你可以使用許多工具來提高應用程序的性能或減小一般類文件的尺寸。這種Java虛擬機的特性和工具可使你在不改變應用程序、或對應用程序僅做很小改動的情況下,
提高應用程序的性能。
Java虛擬機的特性
<!-- frame contents -->
<!-- /frame contents -->
Java2與過去的版本相比, 性能已有很大提高, 其中包括更快的內存分配、類尺寸的減小、垃圾收集的改善、最新型的監控器和作為標准的內聯JIT技術。當使用新的Java2虛擬機時,
你會看到這種性能的改善; 然而, 假如你能夠理解速度是如何提高的, 你就能夠調整你的應用程序, 以充分挖掘每一點性能潛力。
方法內聯
Java虛擬機的Java2版可在運行時自動內聯簡單方法。在一個未優化的Java虛擬機中,每調用一次新的方法,就創建一個新的堆棧幀(stack frame)。創建一個新的堆棧幀需要一些額外的資源以及該棧的某些再映射(re-mapping),其結果將導致系統開銷的少許增加。
由於方法內聯可在你的程序中減少方法調用的次數,因而可提高性能。Java虛擬機內聯代碼內聯了返回常數或僅訪問內部域(internal fields)的方法。為了利用方法內聯,你可以從以下兩件事中選做其一;即:你可以使一個方法對虛擬機所要執行的內聯看上去是有吸引力的,或者你可以手工內聯一個方法,只要它不破壞你的對象模型。在這一語境中的手工內聯意味著可以直接從一個方法中將代碼移動到正在調用該方法的方法中。
下面的小例子演示了虛擬機的自動方法內聯:
public class InlineMe {
int counter=0;
public void method1() {
for(int i=0;i$#@60;1000;i++)
addCount();
System.out.println("counter="+counter);
}
public int addCount() {
counter=counter+1;
return counter;
}
public static void main(String args[]) {
InlineMe im=new InlineMe();
im.method1();
}
}
在當前狀態,addCount方法對虛擬機中的內聯探測器顯得是沒有吸引力的,因為addCount方法返回一個值。要發現該方法是否被內聯:
java -Xrunhprof:cpu=times InlineMe
它生成一個java.hprof.txt輸出文件。前十個方法類似下面的結果:
CPU TIME (ms) BEGIN (total = 510) Thu Jan 28 16:56:15 1999
rank self acc count trace method
1 5.88% 5.88% 1 25 java/lang/Character.
2 3.92% 9.80% 5808 13 java/lang/String.charAt
3 3.92% 13.73% 1 33 sun/misc/Launcher$AppClassLoader.getPermissions
4 3.92% 17.65% 3 31 sun/misc/URLClassPath.getLoader
5 1.96% 19.61% 1 39 java/net/URLClassLoader.Access$1
6 1.96% 21.57% 1000 46 InlineMe.addCount
7 1.96% 23.53% 1 21 sun/io/Converters.newConverter
8 1.96% 25.49% 1 17 sun/misc/Launcher$ExtClassLoader.getExtDirs
9 1.96% 27.45% 1 49 java/util/Stack.peek
10 1.96% 29.41% 1 24 sun/misc/Launcher.
假如你將addCount方法改變為不再返回一個值,則虛擬機可在運行時將其內聯。為使內聯代碼更友好,應用下面的程序替換addCount方法:
public void addCount() {
counter=counter+1;
}
再次運行profiler:
java -Xrunhprof:cpu=times InlineMe
這次,java.hprof.txt的輸出應該顯得是不同的。
AddCount方法已經消失。它已被內聯了!
CPU TIME (ms) BEGIN (total = 560) Thu Jan 28 16:57:02 1999
rank self accum count trace method
1 5.36% 5.36% 1 27 java/lang/Character.
2 3.57% 8.93% 1 23 java/lang/System.initializeSystemClass