JVM内部 -​​ 为什么同一段代码在不同的时间运行?

时间:2012-06-20 05:05:01

标签: java jvm

我正在尝试了解JVM选项并遇到了CompileThreshold选项。我正在运行以下程序:

public class Main {    
    public static void main (String [] args) {    
        for (int repeat = 0; repeat < 200; ++ repeat) {    
            long start = System.nanoTime();    
            sum (100);    
            long end = System.nanoTime();    
            long diff = end - start;    
            System.out.println (repeat + ": " + diff);    
        }    
    }    `

    public static int sum (int n) {
        if (n <= 1)
            return 1;
        else
            return n + sum (n - 1);
    }
}

我得到以下输出:

0: 8555
1: 6416
2: 6416
3: 5988
4: 6416
5: 8555
6: 5989
7: 6416
8: 6416
9: 5988
10: 5561
11: 5988
12: 5988
13: 5988
14: 5988
15: 5988
16: 5988
17: 5988
18: 5988
19: 6416
20: 5988
21: 5988
22: 5988
23: 5988
24: 5560
25: 6416
26: 5988
27: 5561
28: 5560
29: 5989
30: 5989
31: 5988
32: 21814
33: 6416
34: 6843
35: 6416
36: 6844
37: 6416
38: 6416
39: 6844
40: 6416
41: 6415
42: 6416
43: 5988
44: 6416
45: 6844
46: 6416
47: 6416
48: 6416
49: 6416
50: 6416
51: 6416
52: 5988
53: 6416
54: 6844
55: 6843
56: 6416
57: 6844
58: 6416
59: 6416
60: 6415
61: 6416
62: 6416
63: 6416
64: 5988
65: 5988
66: 6416
67: 6416
68: 6844
69: 6416
70: 6416
71: 6416
72: 6416
73: 6416
74: 6415
75: 6416
76: 6416
77: 6416
78: 6416
79: 6415
80: 6844
81: 5988
82: 6415
83: 6416
84: 6416
85: 6416
86: 6416
87: 6416
88: 7272
89: 6416
90: 6416
91: 6844
92: 6844
93: 6415
94: 6416
95: 6415
96: 6415
97: 6416
98: 6416
99: 25236
100: 6416
101: 6416
102: 6843
103: 6416
104: 5988
105: 6416
106: 6415
107: 6416
108: 6416
109: 6416
110: 6416
111: 6416
112: 6416
113: 6844
114: 6416
115: 6416
116: 6416
117: 5988
118: 6416
119: 6416
120: 6416
121: 6415
122: 6416
123: 6415
124: 6416
125: 6416
126: 6416
127: 6416
128: 5988
129: 5988
130: 6416
131: 6416
132: 5988
133: 5988
134: 6416
135: 6416
136: 5989
137: 6416
138: 6416
139: 5988
140: 5988
141: 6416
142: 5560
143: 5988
144: 6416
145: 6843
146: 6415
147: 6416
148: 6843
149: 11549
150: 6416
151: 6844
152: 6416
153: 6415
154: 6416
155: 5988
156: 5988
157: 6416
158: 6416
159: 6416
160: 6416
161: 6415
162: 6416
163: 6416
164: 6416
165: 6416
166: 5988
167: 5988
168: 5988
169: 6416
170: 6416
171: 6416
172: 5988
173: 5988
174: 6844
175: 5988
176: 6416
177: 6416
178: 6844
179: 6416
180: 6415
181: 6416
182: 5988
183: 5989
184: 6416
185: 6416
186: 6416
187: 6416
188: 5989
189: 5560
190: 5988
191: 6416
192: 6415
193: 6416
194: 18820
195: 1711
196: 1284
197: 2139
198: 1711
199: 1711

如果你观察到,在32,99,149,194的时间里会出现峰值。

在194之后,运行时间相对较少。请解释一下这种行为。感谢。

3 个答案:

答案 0 :(得分:2)

最初的尖峰是JIT决定编译代码,其余的是GC运行。

答案 1 :(得分:1)

最常见的HotSpot在JVM重新JITs方法之后,许多调用导致194运行后的加速: http://java.sun.com/docs/books/performance/1st_edition/html/JPAppHotspot.fm.html

  

B.5.3 CompileThreshold

     

默认值:1500

     

示例用法:java -XX:CompileThreshold = 1000000

     

HotSpot的当前实现通常在编译之前等待一定数量的方法执行。不编译每种方法都有助于启动时间并减少RAM占用空间。此选项允许您控制该阈值。通过增加数量,您可以略微减少RAM占用空间,以换取更长的时间,然后程序达到最佳性能。

答案 2 :(得分:0)

恕我直言,这个问题是不完整的,除非你提到在后台/前台运行的其他进程的活动,即在不了解整体系统负载的情况下,很难预测这些时间的原因。运行此类基准测试时,请确保捕获/监控整个系统负载,或者至少确保没有后台活动正在运行,即病毒扫描等。另外,您错过了其他可能至关重要的信息,如JVM版本,平台和核心数量。

是否可以确认相同并重新发布结果?