gpt4 book ai didi

java - 使用 Runtime.getRuntime().totalMemory() 和 freeMemory() 计算内存的结果令人困惑?

转载 作者:行者123 更新时间:2023-11-29 07:37:05 25 4
gpt4 key购买 nike

我使用 Runtime.getRuntime().totalMemory()freeMemory() 来计算内存。但是,我对结果感到困惑。

我已经阅读了以下帖子:

What are Runtime.getRuntime().totalMemory() and freeMemory()?

a question on Runtime.getRuntime().totalMemory()

这是我的演示代码:

package test;

class Memory

{

public static long used()

{

long total=Runtime.getRuntime().totalMemory();

long free=Runtime.getRuntime().freeMemory();

return (total-free);

}

}



package test;

import java.util.ArrayList;

public class MemTestQuestion {

private static final long _10M = 10000000;

public static void main(String[] args) {

int runCount=10;
for (int i = 0; i < runCount; i++) {
arrayListMemTest();
}
}

public static void arrayListMemTest()
{
long startTime = System.currentTimeMillis();
long startMem=Memory.used();

ArrayList<Integer>al= new ArrayList<Integer>();
for (int i = 0; i < _10M; i++) {
al.add(1000);
}

long endMem= Memory.used();
long endEndTime = System.currentTimeMillis();

long timeLast = endEndTime - startTime;
long memUsed = endMem-startMem;


System.out.print("lasts:"
+ timeLast + "ms = "+timeLast/1000.0+"s\t");
System.out.println("mem used:"
+memUsed+"bytes = "+new java.text.DecimalFormat("#.00").format(memUsed/(1024*1024.0))+"M");

System.gc();
}

}

这是当 runCount=1(位于 Main 方法中的变量)时的结果:

lasts:3606ms = 3.606s   mem used:214644488bytes = 204.70M

这是 runCount=10 时的结果:

lasts:3643ms = 3.643s   mem used:214644488bytes = 204.70M
lasts:389ms = 0.389s mem used:254054928bytes = 242.29M
lasts:366ms = 0.366s mem used:219163424bytes = 209.01M
lasts:242ms = 0.242s mem used:256265992bytes = 244.39M
lasts:222ms = 0.222s mem used:255523768bytes = 243.69M
lasts:225ms = 0.225s mem used:253843192bytes = 242.08M
lasts:253ms = 0.253s mem used:253967736bytes = 242.20M
lasts:236ms = 0.236s mem used:253994680bytes = 242.23M
lasts:234ms = 0.234s mem used:254066232bytes = 242.30M
lasts:233ms = 0.233s mem used:254091448bytes = 242.32M

最让我困惑的是,当runCount=10时,最多的结果是240M左右。但是当runCount=1时,结果是200M左右。

我猜这是因为JAVA JVM没有及时收集垃圾,所以第一个结果比较有说服力。 我说得对吗?如果没有,有人可以提供一些线索或其他建议吗?提前致谢。

演示代码的目的是尝试比较标准的 Java 容器和来自第三方的容器。

最佳答案

I guess this is because the JAVA JVM does not collect garbage in time, so the first result are more convicing. Am I right?

我不这么认为。运行 System.gc() 应该是一个“尽最大努力”收集所有垃圾的提示。现在。可以忽略该提示,但如果 GC 确实运行,您会期望它执行 >>full<< 收集,并且仅在完成时返回。应该没有 GC“跟上”的问题。

If not, can someone provide some clues or other suggestions?

这可能是由于 JIT 编译和其他 JVM 预热效果所致。

当您的应用程序启动时,您的代码方法和所有(传递地)使用的库方法都是字节码,并将由字节码解释器解释。在解释字节码时,JVM 会收集有关各种事物的统计信息(例如,协助分支预测)。最终,它决定对这些方法进行 JIT 编译。

那么这与您的观察有何关系?

  1. 统计信息存储在堆中,并且可以访问...直到 JIT 编译器“使用”它们。

  2. JIT 编译器异步运行,并且在运行时还会使用堆空间来保存其数据结构。

  3. 在启动时,JVM 必须加载类,这也会占用堆空间来存放临时对象。

  4. 堆大小不是恒定的。它会增长(有时会缩小),具体取决于每个 GC 周期后有多少可用空间。

在 JVM 预热阶段,所有这些结合起来给出堆大小和堆空间使用的局部“高”和“低”。

关于java - 使用 Runtime.getRuntime().totalMemory() 和 freeMemory() 计算内存的结果令人困惑?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34347655/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com