【问题标题】:Java Runtime.freeMemory() returning bizarre results when adding more objects添加更多对象时,Java Runtime.freeMemory() 返回奇怪的结果
【发布时间】:2012-12-12 22:33:21
【问题描述】:

无论出于何种原因,我都想看看我可以创建多少个对象并用它填充LinkedList。我使用Runtime.getRuntime().freeMemory() 来获得JVM 中可用内存的近似值。我是这样写的:

public static void main(String[] arg) {
    Scanner kb = new Scanner(System.in);
    List<Long> mem = new LinkedList<Long>();
    while (true) {
        System.out.println("Max memory: " + Runtime.getRuntime().maxMemory() + ". Available memory: " + Runtime.getRuntime().freeMemory() + " bytes. Press enter to use more.");
        String s = kb.nextLine();
        if (s.equals("m"))
        for (int i = 0; i < 1000000; i++) {
            mem.add(new Long(Long.MAX_VALUE));
        }
    }
}

如果我输入m,应用程序会在列表中添加一百万个Long 对象。你会认为对象越多(我们有引用,所以不能被 gc'ed),可用内存就越少。运行代码:

Max memory: 1897725952. Available memory: 127257696 bytes.
m
Max memory: 1897725952. Available memory: 108426520 bytes.
m
Max memory: 1897725952. Available memory: 139873296 bytes.
m
Max memory: 1897725952. Available memory: 210632232 bytes.
m
Max memory: 1897725952. Available memory: 137268792 bytes.
m
Max memory: 1897725952. Available memory: 239504784 bytes.
m
Max memory: 1897725952. Available memory: 169507792 bytes.
m
Max memory: 1897725952. Available memory: 259686128 bytes.
m
Max memory: 1897725952. Available memory: 189293488 bytes.
m
Max memory: 1897725952. Available memory: 387686544 bytes.

可用内存波动。这是怎么发生的? GC 是否正在清理其他东西(堆上还有哪些其他东西需要真正清理?),freeMemory() 方法是否返回了一个离我们很远的近似值?我是错过了什么还是我疯了?

【问题讨论】:

  • 嗯,您在每次迭代中创建一个新的 Random 对象。所有这些对象都必须经过 GC。
  • 您没有保留对Random 对象的引用
  • @durron597 对我来说很好
  • 如果 Xms != Xmx,提交的内存可能会增加。在您的 JVM 上插入 JVisualVM(带有 VisualGC 插件)以获得更多洞察力。或者给我们你的 JVM 参数。
  • 我尝试了 Random,我也尝试了 Long.MAX_VALUE,我得到了类似的结果。将其更新为有问题的 Long.MAX_VALUE。

标签: java memory-management garbage-collection


【解决方案1】:

随着您消耗更多内存,堆会增长。请注意,freeMemory() 报告相对于当前堆大小的使用情况,该大小可能会增长。检查totalMemory() 而不是maxMemory()。如果我没记错的话。

或者您是在问正在分配的哪些内容可能会被垃圾回收?

  • 你在循环中分配的Random
  • 在从 OS 流中读取、解析为字符、然后解析为行的过程中分配的对象
  • 可能在调用期间分配了一些东西来检查空闲内存本身

【讨论】:

  • 我不知道堆是可变大小的。所以JVM中的内存就像:[ ALL MEMORY [&lt;&lt;&lt;HEAP&gt;&gt;&gt;][&lt;&lt;STACK&gt;&gt;]]?两者都可以根据需要在最大内存范围内增长吗?
  • 不,Java 在堆满时从操作系统获取更多内存以扩展 JVM 内存。达到 Xmx 限制。您可以强制它使用 Xms 预先获取所有内容。
猜你喜欢
  • 2019-02-04
  • 2019-06-20
  • 2012-08-08
  • 2012-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多