gpt4 book ai didi

java - 这个演示中的 JVM 内存分配和释放解释?

转载 作者:搜寻专家 更新时间:2023-11-01 02:19:07 24 4
gpt4 key购买 nike

我有一个简单的演示来检查 JVM 内存分配和释放的细节。

Java 版本

$ java -version
java version "1.8.0_201"
Java(TM) SE Runtime Environment (build 1.8.0_201-b09)
Java HotSpot(TM) 64-Bit Server VM (build 25.201-b09, mixed mode)

演示

/**
* VM Options: -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8
*/
public class DefaultCollector {
private static final int _1MB = 1024 * 1024;
public static void main(String... args) {
byte[] arr1 = new byte[2 * _1MB];
byte[] arr2 = new byte[2 * _1MB];
byte[] arr3 = new byte[2 * _1MB];
byte[] arr4 = new byte[4 * _1MB];
}
}

GC 日志

[GC (Allocation Failure) [PSYoungGen: 6516K->695K(9216K)] 6516K->4791K(19456K), 0.0019189 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] 
Heap
PSYoungGen total 9216K, used 7408K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000)
eden space 8192K, 81% used [0x00000000ff600000,0x00000000ffc8e6a8,0x00000000ffe00000)
from space 1024K, 67% used [0x00000000ffe00000,0x00000000ffeadcb0,0x00000000fff00000)
to space 1024K, 0% used [0x00000000fff00000,0x00000000fff00000,0x0000000100000000)
ParOldGen total 10240K, used 4096K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000)
object space 10240K, 40% used [0x00000000fec00000,0x00000000ff000020,0x00000000ff600000)
Metaspace used 3273K, capacity 4556K, committed 4864K, reserved 1056768K
class space used 357K, capacity 392K, committed 512K, reserved 1048576K
Disconnected from the target VM, address: '127.0.0.1:38815', transport: 'socket'

我的问题

  1. -Xms20M -Xmx20M -Xmn10M -XX:SurvivorRatio=8 已经设置好并且 eden - 8M, from - 1M, and to - 1M 显示的很清楚,为什么 PSYoungGen 总计 9216K 而不是 10240K
  2. 为什么 Allocation Failure 因为 Tenured 中仍有空间,而 -XX:+HandlePromotionFailure 自 JDK 6 及更高版本以来默认应为 true
  3. 为什么 PSYoungGen: 6516K->695K(9216K) 因为这三个数组在年轻一代中仍然存在?是因为分配失败吗?
  4. 为什么 Metaspace 占用这么多内存 Metaspace 使用了 3273K?如果不只是输入信息,那里面到底有什么?

我还尝试了其他组合:

  1. 大小:1, 1, 1, 4 => eden 70%,tenured 40%

    为什么?难道不应该都在伊甸园吗?

  2. 大小:1, 1, 1, 1 => eden 80% (~6M),tenured 0%

    为什么在 eden 中是 80%(~6M)而不是 4M?

已更新

在@Stephen C 的帮助下,我发现在登录 IntelliJ 终端 之前有一个输出为

/usr/lib/jvm/java-8-oracle/bin/java -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:42103,suspend=y,server=n -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8 -javaagent:/home/hearen/Downloads/idea-IU-183.5429.30/lib/rt/debugger-agent.jar -Dfile.encoding=UTF-8 -classpath /usr/lib/jvm/java-8-oracle/jre/lib/charsets.jar:/usr/lib/jvm/java-8-oracle/jre/lib/deploy.jar:/usr/lib/jvm/java-8-oracle/jre/lib/ext/cldrdata.jar:/usr/lib/jvm/java-8-oracle/jre/lib/ext/dnsns.jar:/usr/lib/jvm/java-8-oracle/jre/lib/ext/jaccess.jar:/usr/lib/jvm/java-8-oracle/jre/lib/ext/jfxrt.jar:/usr/lib/jvm/java-8-oracle/jre/lib/ext/localedata.jar:/usr/lib/jvm/java-8-oracle/jre/lib/ext/nashorn.jar:/usr/lib/jvm/java-8-oracle/jre/lib/ext/sunec.jar:/usr/lib/jvm/java-8-oracle/jre/lib/ext/sunjce_provider.jar:/usr/lib/jvm/java-8-oracle/jre/lib/ext/sunpkcs11.jar:/usr/lib/jvm/java-8-oracle/jre/lib/ext/zipfs.jar:/usr/lib/jvm/java-8-oracle/jre/lib/javaws.jar:/usr/lib/jvm/java-8-oracle/jre/lib/jce.jar:/usr/lib/jvm/java-8-oracle/jre/lib/jfr.jar:/usr/lib/jvm/java-8-oracle/jre/lib/jfxswt.jar:/usr/lib/jvm/java-8-oracle/jre/lib/jsse.jar:/usr/lib/jvm/java-8-oracle/jre/lib/management-agent.jar:/usr/lib/jvm/java-8-oracle/jre/lib/plugin.jar:/usr/lib/jvm/java-8-oracle/jre/lib/resources.jar:/usr/lib/jvm/java-8-oracle/jre/lib/rt.jar:/home/hearen/git/personal/about-java/target/classes:/usr/lib/jvm/java-8-oracle/lib/dt.jar:/usr/lib/jvm/java-8-oracle/lib/tools.jar:/usr/lib/jvm/java-8-oracle/lib/sa-jdi.jar:/usr/lib/jvm/java-8-oracle/lib/jconsole.jar:/usr/lib/jvm/java-8-oracle/lib/packager.jar:/usr/lib/jvm/java-8-oracle/lib/javafx-mx.jar:/usr/lib/jvm/java-8-oracle/lib/ant-javafx.jar:/home/hearen/.m2/repository/org/projectlombok/lombok/1.16.20/lombok-1.16.20.jar:/home/hearen/.m2/repository/junit/junit/4.11/junit-4.11.jar:/home/hearen/.m2/repository/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar:/home/hearen/.m2/repository/cglib/cglib/3.2.4/cglib-3.2.4.jar:/home/hearen/.m2/repository/org/ow2/asm/asm/5.1/asm-5.1.jar:/home/hearen/.m2/repository/org/apache/ant/ant/1.9.6/ant-1.9.6.jar:/home/hearen/.m2/repository/org/apache/ant/ant-launcher/1.9.6/ant-launcher-1.9.6.jar:/home/hearen/Downloads/idea-IU-183.5429.30/lib/idea_rt.jar jvm.allocation.DefaultCollector

然后我手动使用CLI编译并运行程序

$ javac DefaultCollector.java 
$ java -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8 DefaultCollector

然后输出变成

Heap
PSYoungGen total 9216K, used 6815K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000)
eden space 8192K, 83% used [0x00000000ff600000,0x00000000ffca7ff8,0x00000000ffe00000)
from space 1024K, 0% used [0x00000000fff00000,0x00000000fff00000,0x0000000100000000)
to space 1024K, 0% used [0x00000000ffe00000,0x00000000ffe00000,0x00000000fff00000)
ParOldGen total 10240K, used 4096K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000)
object space 10240K, 40% used [0x00000000fec00000,0x00000000ff000010,0x00000000ff600000)
Metaspace used 2464K, capacity 4486K, committed 4864K, reserved 1056768K
class space used 265K, capacity 386K, committed 512K, reserved 1048576K

显然大数组 4M 直接进入 Tenured 而其他三个 2M 分配在 Young 中我们上面的结果。

最佳答案

我怀疑其中大部分可以用 JVM 中的“其他东西”来解释。

输出的最后一行证明您有一个代理连接到您的 JVM。

Disconnected from the target VM, address: '127.0.0.1:38815', transport: 'socket'

据我所知,代理将导致 JVM 加载、编译等您的应用程序不直接使用的类。然后代理将为套接字、缓冲区等分配堆对象以处理监控。

这会增加常规堆和元空间的使用。

我建议您在没有附加代理的情况下从 shell/命令行重复这个实验。通过命令行选项打开 GC 日志记录来获取 GC 统计信息。


您的更新。

Apparently the big array 4M is directly into the Tenured while the other three 2M allocated in Young giving us the above results.

正确。有一个阈值,高于该阈值的对象将直接分配到永久空间中。它可以被调整....

关于java - 这个演示中的 JVM 内存分配和释放解释?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55174384/

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