利用虚拟机特性,提高程序性能(方法内联)

Java2与过去的版本相比,性能已有大幅提高,其中包括: 更快的内存分配,更小的类尺寸,垃圾收集性能的改善,还有最新型的监控器和作为标准的内联JIT(Just-In-Time)技术。

在使用Java2虚拟机时,会看到这些性能的改善,然后,如果能够理解速度是怎样提高的,您就能够调整您的应用程序,以充分挖掘每一点性能潜力。

[b]方法内联[/b]
新版的JVM可以在运行时 自动内联 简单方法。 在一个未优化的JVM中,每调用一次新的方法,就创建一个新的堆栈框架(stack frame)。 创建一个新的stack frame需要一些额外的资源,其结果是导致系统开销的少许增加。

由于方法内联可在你的程序中减少方法调用的次数,避免了上面谈到的开销,因而可以提高性能。JVM内联代码 内联了 返回常数 或 仅仅访问内部域的方法。为了利用方法内联,可以从一下两件事中选做其一:
(1)使一个方法对JVM所有执行的内联看上去是有吸引力的
(2)在不破坏对象模型的前提下,手工内联一个方法。这里手工内联意味着可以直接从一个方法中将代码移动到正在调用该方法的方法中。

下面的小例子,演示了JVM的自动方法内联:

[code]public class InlineMe {
int counter = 0;
public void method1() {
for (int i=0;i<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();
}
}[/code]

在当前状态,addCount方法对JVM中内联探测器显得是没有什么吸引力的,因为addCount方法返回一个值。 要发现该方法是否被内联:

java -Xrunhprof:cpu=times InlineMe

它生成一个java.hprof.txt输出文件。类似下面的结果:

CPU TIME (ms) BEGIN (total = 1672) Thu Nov 08 19:37:06 2007
rank self accum count trace method
1 12.14% 12.14% 2000 300927 sun.nio.cs.ext.DoubleByteEncoder.encodeArrayLoop
2 6.58% 18.72% 2000 300953 sun.nio.cs.StreamEncoder.writeBytes
3 6.52% 25.24% 2000 300931 java.nio.charset.CharsetEncoder.encode
4 3.71% 28.95% 2000 300950 java.io.BufferedOutputStream.flush
5 2.87% 31.82% 2000 300934 sun.nio.cs.StreamEncoder.implWrite
6 2.87% 34.69% 2000 300913 java.nio.HeapCharBuffer.<init>
7 2.75% 37.44% 2001 300085 java.nio.Buffer.<init>
8 1.91% 39.35% 1000 300955 sun.nio.cs.StreamEncoder.flushBuffer
9 1.91% 41.27% 1000 300895 java.lang.StringBuilder.<init>
10 1.91% 43.18% 2000 300916 java.nio.CharBuffer.hasArray
11 1.91% 45.10% 1000 300960 java.io.PrintStream.print
12 1.91% 47.01% 1000 300975 sun.nio.cs.StreamEncoder.flushBuffer
13 1.91% 48.92% 1000 300978 java.io.OutputStream.flush
14 1.91% 50.84% 2000 300947 java.io.FileOutputStream.write
15 1.91% 52.75% 2000 300941 java.nio.Buffer.limit
16 1.91% 54.67% 2001 300083 java.nio.Buffer.limit
17 1.91% 56.58% 1000 300935 sun.nio.cs.StreamEncoder.write
18 1.91% 58.49% 12893 300924 sun.nio.cs.Surrogate.is
19 1.85% 60.35% 2000 300932 java.nio.charset.CoderResult.isUnderflow
20 1.85% 62.20% 6000 300923 java.nio.ByteBuffer.arrayOffset
21 1.85% 64.06% 1000 300954 sun.nio.cs.StreamEncoder.implFlushBuffer
22 1.85% 65.91% 6000 300919 java.nio.CharBuffer.arrayOffset
23 1.85% 67.76% 2000 300933 java.nio.Buffer.remaining
24 1.79% 69.56% 2000 300948 java.io.BufferedOutputStream.flushBuffer
25 1.79% 71.35% 1000 300980 java.io.PrintStream.newLine
26 1.79% 73.15% 1000 300971 java.io.OutputStreamWriter.write
27 0.96% 74.10% 12893 300925 sun.nio.cs.ext.DoubleByteEncoder.encodeSingle
28 0.96% 75.06% 1000 300959 java.io.PrintStream.write
29 0.96% 76.02% 2000 300915 java.nio.Buffer.hasRemaining
30 0.96% 76.97% 2000 300928 sun.nio.cs.ext.DoubleByteEncoder.encodeLoop
31 0.96% 77.93% 1000 300909 java.io.Writer.write
32 0.96% 78.89% 1000 300967 java.io.Writer.write
33 0.96% 79.84% 1000 300894 java.lang.StringBuilder.append
34 0.96% 80.80% 1 300629 sun.net.www.ParseUtil.decode
[color=red] 35 0.96% 81.76% 1 300982 com.spr.base.InlineMe.method1[/color]
36 0.96% 82.72% 5 300276 java.lang.String.toLowerCase
37 0.96% 83.67% 5 300260 java.io.Win32FileSystem.normalize
38 0.96% 84.63% 12 300174 java.net.URL.getRef
39 0.96% 85.59% 1000 300937 java.io.BufferedWriter.flushBuffer
40 0.96% 86.54% 1000 300964 java.io.BufferedWriter.min
41 0.90% 87.44% 1000 300972 java.io.BufferedWriter.flushBuffer
42 0.90% 88.34% 1000 300966 java.io.BufferedWriter.write
43 0.90% 89.23% 1000 300961 java.io.PrintStream.ensureOpen
44 0.90% 90.13% 2000 300952 java.nio.Buffer.clear
45 0.90% 91.03% 2000 300946 java.io.BufferedOutputStream.write
46 0.90% 91.93% 2000 300940 java.nio.Buffer.flip
47 0.90% 92.82% 2000 300917 java.nio.ByteBuffer.hasArray
48 0.90% 93.72% 2000 300914 java.nio.CharBuffer.wrap
49 0.90% 94.62% 1000 300908 java.io.BufferedWriter.write
50 0.90% 95.51% 1000 300893 java.lang.AbstractStringBuilder.append
51 0.90% 96.41% 1000 300890 java.lang.AbstractStringBuilder.<init>
[color=red] 52 0.90% 97.31% 1000 300881 com.spr.base.InlineMe.addCount[/color]
53 0.90% 98.21% 1000 300968 java.io.BufferedWriter.newLine
54 0.90% 99.10% 27 300439 java.lang.String.charAt
55 0.90% 100.00% 1 300114 java.lang.StringCoding$StringDecoder.decode
CPU TIME (ms) END


如果将addCount方法改造为不再返回一个值,则虚拟机可在运行时将其内联:

[code]public void addCount() {
counter = counter+1;
}[/code]
再次运行profiler
java -Xrunhprof:cpu=times InlineMe
这次,java.hprof.txt的输出应该是不同的。addCount方法已经找不到了,它被内联了!

CPU TIME (ms) BEGIN (total = 1688) Thu Nov 08 19:45:06 2007
rank self accum count trace method
1 22.33% 22.33% 2000 300927 sun.nio.cs.ext.DoubleByteEncoder.encodeArrayLoop
2 6.46% 28.79% 12893 300924 sun.nio.cs.Surrogate.is
3 4.68% 33.47% 1000 300980 java.io.PrintStream.newLine
4 4.62% 38.09% 2000 300953 sun.nio.cs.StreamEncoder.writeBytes
5 2.84% 40.94% 2000 300934 sun.nio.cs.StreamEncoder.implWrite
6 2.78% 43.72% 2000 300931 java.nio.charset.CharsetEncoder.encode
7 2.78% 46.50% 1000 300966 java.io.BufferedWriter.write
8 2.78% 49.29% 1000 300938 sun.nio.cs.StreamEncoder.isOpen
9 2.73% 52.01% 2000 300928 sun.nio.cs.ext.DoubleByteEncoder.encodeLoop
10 1.90% 53.91% 2000 300944 java.nio.ByteBuffer.arrayOffset
11 1.84% 55.75% 2000 300932 java.nio.charset.CoderResult.isUnderflow
12 1.84% 57.58% 2000 300950 java.io.BufferedOutputStream.flush
13 1.84% 59.42% 2000 300947 java.io.FileOutputStream.write
14 1.84% 61.26% 1000 300976 java.io.OutputStreamWriter.flushBuffer
15 1.84% 63.09% 2000 300941 java.nio.Buffer.limit
16 1.84% 64.93% 1000 300975 sun.nio.cs.StreamEncoder.flushBuffer
[color=red] 17 1.84% 66.77% 1 300982 com.spr.base.InlineMe.method1[/color]
18 1.78% 68.54% 1000 300972 java.io.BufferedWriter.flushBuffer
19 1.78% 70.32% 1000 300935 sun.nio.cs.StreamEncoder.write
20 0.95% 71.27% 1000 300973 sun.nio.cs.StreamEncoder.isOpen
21 0.95% 72.22% 1000 300974 sun.nio.cs.StreamEncoder.implFlushBuffer
22 0.95% 73.16% 16 300238 java.lang.AbstractStringBuilder.expandCapacity
23 0.95% 74.11% 1000 300960 java.io.PrintStream.print
24 0.95% 75.06% 1000 300959 java.io.PrintStream.write
25 0.95% 76.01% 1000 300958 java.lang.String.indexOf
26 0.95% 76.95% 2000 300949 java.io.OutputStream.flush
27 0.95% 77.90% 5 300295 sun.misc.URLClassPath$JarLoader.<init>
28 0.95% 78.85% 2000 300940 java.nio.Buffer.flip
29 0.95% 79.80% 1000 300937 java.io.BufferedWriter.flushBuffer
30 0.95% 80.75% 1000 300979 java.io.BufferedOutputStream.flush
31 0.95% 81.69% 2000 300929 java.nio.charset.CoderResult.isOverflow
32 0.95% 82.64% 6000 300923 java.nio.ByteBuffer.arrayOffset
33 0.95% 83.59% 4000 300921 java.nio.Buffer.limit
34 0.95% 84.54% 2001 300084 java.nio.Buffer.position
35 0.95% 85.49% 6000 300919 java.nio.CharBuffer.arrayOffset
36 0.95% 86.43% 2000 300917 java.nio.ByteBuffer.hasArray
37 0.95% 87.38% 6 300580 java.lang.Integer.parseInt
38 0.95% 88.33% 1000 300908 java.io.BufferedWriter.write
39 0.95% 89.28% 1000 300890 java.lang.AbstractStringBuilder.<init>
40 0.95% 90.23% 1000 300901 java.lang.String.<init>
41 0.89% 91.11% 1000 300896 java.lang.AbstractStringBuilder.stringSizeOfInt
42 0.89% 92.00% 1000 300892 java.lang.String.getChars
43 0.89% 92.89% 1000 300902 java.lang.StringBuilder.toString
44 0.89% 93.78% 2 300661 java.io.Win32FileSystem.normalize
45 0.89% 94.67% 2000 300914 java.nio.CharBuffer.wrap
46 0.89% 95.56% 1000 300978 java.io.OutputStream.flush
47 0.89% 96.45% 1 300352 sun.net.www.ParseUtil.decode
48 0.89% 97.33% 2000 300945 java.io.PrintStream.ensureOpen
49 0.89% 98.22% 1000 300963 java.io.BufferedWriter.ensureOpen
50 0.89% 99.11% 4000 300920 java.nio.Buffer.position
51 0.89% 100.00% 2001 300083 java.nio.Buffer.limit
CPU TIME (ms) END
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值