gpt4 book ai didi

java - Java 8 与 Java 9 之间的内存分配是否存在差异?

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:07:45 35 4
gpt4 key购买 nike

我想在 Java 中试验 -Xmx 选项,并创建了一个简单的测试程序,该程序一次分配 1 Mib,直到内存不足。

import java.util.Vector;

public class MemoryMuncher {
static final int MiB = 1048576;
static final int accellerator = 1;

public static void main(String[] args) {
Vector victor = new Vector();
int i = 1;
try {
while (true) {
byte roger[] = new byte[MiB * accellerator];
victor.add(roger);
Runtime rt = Runtime.getRuntime();
System.out.printf("free: %,6d\t\ttotal: %,6d\t\tallocated: %,6d \n", rt.freeMemory()/MiB, rt.totalMemory()/MiB, i++*accellerator);
}
} catch (OutOfMemoryError e) {
System.out.println(e);
}
}
}

当我使用 -Xmx 选项运行程序时,我注意到 Java 8 (1.8.0.131) 和 Java 9 (9.0.1) 之间的行为差​​异。

Java 8 的工作方式接近我的预期。当我使用 -Xmx256M 运行程序时,它会在抛出 OutOfMemoryError 之前分配 233MiB。

free:    361        total:    368       allocated:      1 
free: 360 total: 368 allocated: 2
...
free: 12 total: 245 allocated: 232
free: 11 total: 245 allocated: 233
java.lang.OutOfMemoryError: Java heap space

但是,当我使用 Java 9 运行相同的程序时,它只运行了大约 一半 (127 MiB) 就出现异常。这是一致的。如果我将 -Xmx 更改为 512M 或 1024M,它只会达到该数量的一半(分别为 255 MiB 和 510 MiB)。我对这种行为没有任何解释。

free:    250        total:    256       allocated:      1 
free: 247 total: 256 allocated: 2
...
free: 2 total: 256 allocated: 126
free: 1 total: 256 allocated: 127
java.lang.OutOfMemoryError: Java heap space

我在文档中搜索了 Java 8 和 Java 9 之间内存管理的任何变化,但没有找到任何东西。

有没有人知道为什么 Java 9 在某些情况下会以不同于以前的 Java 版本的方式管理/分配内存?

最佳答案

我找到了 this关于 Java 9 计划如何以不同方式进行垃圾收集的非常有趣的文章。

更具体地说,Java 9 计划使用 G1 垃圾收集器将内存划分为固定大小。您的代码可能正在做的是触发内存拆分为 Java 9 的两个固定大小的 block 。这样做的原因是它将节省另一半内存用于移动所有内容并“压缩”仍在使用的内存。但是,因为您只是继续使用内存,所以当使用了 ~1/2 内存时它会立即中断。我不确定你的 CS 有多严格,但在我的学校我们研究了简单的垃圾技术,G1GC 让我想起的一个如此简单的技术是 stop-and-copy。该技术在内存的两半之间切换分配的内存,同时在执行此操作时“压缩”内存。

在 Java 8 中,使用了并行收集器,它与 G1GC 不同,因为它只关心吞吐量。因此,接近 100% 的真实堆将被使用,代价是更长的 GC 时间。当然,这是两个版本之间的权衡,但您可以通过明确指定要使用的 GC 类型来解决这个问题。例如,如果在 Java 9 上使用选项:

-XX:UseParallelGC

您应该会看到与使用 Java 8 时相同的行为。我链接的文章有所有不同的选项,但我想您明白了。希望这有助于/回答您的问题,实际上直到您提出它我才意识到这一点,所以感谢您让我意识到这一点。

编辑:根据Oracle他们自己说,新的 G1 垃圾收集器是为高内存机器设计的,再次说明了为什么他们不会利用完整的堆空间来减少 GC 时间。

关于java - Java 8 与 Java 9 之间的内存分配是否存在差异?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52023506/

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