java – 这个演示中的JVM内存分配和解除分配解释了什么?
作者:互联网
我有一个简单的演示来检查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'
我的问题
> -Xms20M -Xmx20M -Xmn10M -XX:SurvivorRatio = 8已经设置,而eden – 8M,从 – 1M,到 – 1M清楚显示,为什么PSYoungGen总计9216K而不是10240K?
>为什么分配失败,因为Tenured和-XX:+HandlePromotionFailure
中仍有空格应该是默认的,因为JDK 6及以后已经存在?
>为什么PSYoungGen:6516K-> 695K(9216K)因为这三个阵列在Young Generation中还活着?是因为分配失败了吗?
>为什么Metaspace
占用这么多内存Metaspace使用3273K?究竟是什么,如果不只是类型信息?
我也试过其他组合:
>尺寸:1,1,1,4 =>伊甸园70%,终身40%
为什么?不应该全部在伊甸园吗?
>尺寸:1,1,1,1 =>伊甸园80%(约6M),终身0%
为什么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'
AFAIK,代理将导致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,garbage-collection,jvm-hotspot,java-8 来源: https://codeday.me/bug/20190607/1193575.html