我有一些描述 Runtime.freeMemory 的代码。这是我的代码:
package misc;
import java.util.ArrayList;
import java.util.Random;
public class FreeMemoryTest {
private final ArrayList<Double> l;
private final Random r;
public FreeMemoryTest(){
this.r = new Random();
this.l = new ArrayList<Double>();
}
public static boolean memoryCheck() {
double freeMem = Runtime.getRuntime().freeMemory();
double totalMem = Runtime.getRuntime().totalMemory();
double fptm = totalMem * 0.05;
boolean toReturn = fptm > freeMem;
return toReturn;
}
public void freeMemWorkout(int max){
for(int i = 0; i < max; i++){
memoryCheck();
l.add(r.nextDouble());
}
}
public void workout(int max){
for(int i = 0; i < max; i++){
l.add(r.nextDouble());
}
}
public static void main(String[] args){
FreeMemoryTest f = new FreeMemoryTest();
int count = Integer.parseInt(args[1]);
long startTime = System.currentTimeMillis();
if(args[0].equals("f")){
f.freeMemWorkout(count);
} else {
f.workout(count);
}
long endTime = System.currentTimeMillis();
System.out.println(endTime - startTime);
}
}
当我使用 -Xrunhprof:cpu=samples 运行分析器时,绝大多数调用都是针对 Runtime.freeMemory() 的,如下所示:
CPU SAMPLES BEGIN (total = 531) Fri Dec 7 00:17:20 2012
rank self accum count trace method
1 83.62% 83.62% 444 300274 java.lang.Runtime.freeMemory
2 9.04% 92.66% 48 300276 java.lang.Runtime.totalMemory
当我使用 -Xrunhprof:cpu=time 运行分析器时,我根本看不到对 Runtime.freeMemory 的任何调用,前五个调用如下:
CPU TIME (ms) BEGIN (total = 10042) Fri Dec 7 00:29:51 2012
rank self accum count trace method
1 13.39% 13.39% 200000 307547 java.util.Random.next
2 9.69% 23.08% 1 307852 misc.FreeMemoryTest.freeMemWorkout
3 7.41% 30.49% 100000 307544 misc.FreeMemoryTest.memoryCheck
4 7.39% 37.88% 100000 307548 java.util.Random.nextDouble
5 4.35% 42.23% 100000 307561 java.util.ArrayList.add
这两个配置文件彼此如此不同。我认为样本应该至少大致近似于时代的结果,但在这里我们看到了一个非常根本的差异,消耗超过 80% 的样本的东西甚至没有出现在时代概况中。这对我来说没有任何意义,有谁知道为什么会这样?
更多关于这个:
$ java -Xmx1000m -Xms1000m -jar memtest.jar a 20000000 5524
//does not have the calls to Runtime.freeMemory()
$ java -Xmx1000m -Xms1000m -jar memtest.jar f 20000000 9442
//has the calls to Runtime.freeMemory()
使用 freemem 运行所需的时间大约是不使用它运行的时间的两倍。如果 80% 的 CPU 时间花在 java.Runtime.freeMemory() 中,并且我删除了该调用,我希望程序加速大约 5 倍。正如我们在上面看到的,程序加速约 2 的因数。
5 倍的减速比经验上观察到的 2 倍的减速要糟糕得多,所以我不明白采样分析器与现实的距离如此之远。