添加更多对象时,Java Runtime.freeMemory() 返回奇怪的结果

标签 java memory-management garbage-collection

无论出于何种原因,我想看看可以创建多少个对象并填充 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 对象。您可能会认为对象越多(我们有引用,因此无法对其进行垃圾回收),可用内存就越少。运行代码:

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() 方法是否返回了一个偏离的近似值?我错过了什么还是我疯了?

最佳答案

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

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

  • 您在循环中分配的随机
  • 在从操作系统流读取、解析为字符、然后解析为行的过程中分配的对象
  • 可能在调用期间分配了一些内容来检查可用内存本身

关于添加更多对象时,Java Runtime.freeMemory() 返回奇怪的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13849851/

相关文章:

php - 在 PHP 中运行密集的批处理,并避免内存耗尽

c - 我怎么知道c中指针变量的分配内存大小

ruby - 为什么这个 XML 解析 Ruby 代码在禁用 GC 的情况下运行得更慢?

c - Windows 和 Linux 上的内存页面写入检测

java - 如何从 Android 应用程序向 WHMCS 安装发送正确的发布请求?

java - 如何杀死在服务器上运行的进程

java - 如何将任意字符串转换为 Java 标识符?

java - 动态调整咖啡因缓存的大小

c++ - 这会彻底清除类对象动态分配的结果吗?

java - 如何防止对象被垃圾收集?