java - 分析调用 Runtime.freeMemory() 的 java 代码

标签 java profiling

我有一些分析 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 运行所需的时间大约是不使用 freemem 时运行时间的两倍。如果 80% 的 CPU 时间花费在 java.Runtime.freeMemory() 上,并且我删除了该调用,那么我预计程序的速度会提高大约 5 倍。正如我们在上面所看到的,程序的速度会加快大约为 2 的系数。

5 倍的减速比根据经验观察到的 2 倍的减速要糟糕得多,所以我不明白的是采样分析器为何与现实相差如此之远。

最佳答案

运行时 freeMemory() 和totalMemory() 是 native 调用。

参见http://www.docjar.com/html/api/java/lang/Runtime.java.html

计时器无法对它们计时,但采样器可以。

关于java - 分析调用 Runtime.freeMemory() 的 java 代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13757641/

相关文章:

java - 我完全从内存运行算法(无 IO),但我的 CPU 使用率低于 25%。可能的瓶颈是什么?

java - 如何强制我的数组为特定长度 - Java

java - 带有 IF 函数的 OnClick 监听器

c# - 确定堆上对象的对象分配发生的位置

linux - 从预编译的 Linux 内核模块中删除对 __gnu_mcount_nc 的引用

performance - 在 Chrome devtools 时间轴上自动化/重播

django - 如何对网站进行分析?

java - 如何在 fragment 之间实现滑动手势?

java - 使用 cookie 进行 GWT 单元测试

java - 如何防止在使用页面上的任何按钮时触发 rowSelector 的 clickAction 方法?