我的代码是:

public class Memory {
// Dummy Entity representing usual data objects
private static class Entity {
    public String name;
    public String detail;
    public Double amount;
    public Integer age;
}

// Linked list offers table inserts and helps illustrating the issue by using multiple
// references per entry
public static java.util.LinkedList<Entity> entities = new java.util.LinkedList<>();

// This threshold should be 2 times Xmn. It ensures the loop stops before a full GC happens.
private static final int MB = 1024 * 1024;
private static final int THRESHOLD = 100 * MB;

public static void main(String[] args) {
    System.out.println("Total Memory (in bytes): " + Runtime.getRuntime().totalMemory());
    System.out.println("Free Memory (in bytes): " + Runtime.getRuntime().freeMemory());
    System.out.println("Max Memory (in bytes): " + Runtime.getRuntime().maxMemory());

    while (true) {
        appendEntitiesToDataStructure();
        terminateBeforeFullGCorOOMEcanHappen();
    }
}

private static void appendEntitiesToDataStructure() {
    entities.add(new Entity());
}

private static void terminateBeforeFullGCorOOMEcanHappen() {
    if (Runtime.getRuntime().freeMemory() < THRESHOLD) {
        System.out.println("Elements created and added to LinkedList: " + entities.size());
        System.exit(0);
    }
}}

启动:

java -Xms${i}g -Xmx${i}g -Xmn50m memory.java >> output.txt

idea :我想知道JVM堆大小在演变时的行为.

堆大小:从1 GB到100 GB

GC测试:G1c、ZGC、PGC

结果:使用g1c和pgc会出现从32 GB开始的回归--随着堆大小的增加,我可以在对象中存储更少的数据.

模式:X:我的对象的大小;Y:堆大小

我不知道该如何解释这种行为--&gt;你知道吗?

java g1gc java gpc java zgc

推荐答案

请参阅本文:https://www.baeldung.com/jvm-compressed-oops

首先,让我们来了解一下OOP是什么:

HotSpot JVM使用称为oops或普通对象指针的数据 struct 来表示对象.这些面向对象操作相当于本机C指针.The 101 are a special kind of oop that represents the object instances in Java.此外,JVM还支持保留在OpenJDK source tree中的其他几个OOP.

更有甚者

enter image description here

一个非常巧妙的功能是将OOPS压缩到32位:

事实证明,JVM可以通过压缩对象指针或OOP来避免浪费内存,因此我们可以两全其美:allowing more than 4 GB of heap space with 32-bit references in 64-bit machines!

最后:

要启用OOP压缩,我们可以使用-XX:+UseCompressedOops调优标志.从Java 7开始,只要最大堆大小小于32 GB,OOP压缩就是默认行为.When the maximum heap size is more than 32 GB, the JVM will automatically switch off the oop compression.因此,需要以不同的方式管理超过32 GB堆大小的内存利用率.

因此,您的问题的答案是:您只是超过了32 GB作为最大堆大小的阈值.

Proof

查看您的图表,可以看到我们所讨论的行为发生在32 GB级别.

Java相关问答推荐

Spring Webocket:尽管凭据设置为False,但MLhttpsify和Fetch请求之间的CORS行为存在差异

伪类focus-in不适用于PFA中的选项卡

有没有一种方法使保持活动设置专用于java.net.http.HttpClient的一个实例

是否保证在事务性块的末尾标记违反约束?

如何找到MongoDB文档并进行本地化?

Hibernate EmptyInterceptor可以工作,但不能拦截器

无法初始化JPA实体管理器工厂:无法确定为Java类型<;类>;推荐的JdbcType

在Spring Boot应用程序中导致";MediaTypeNotSupportdException&qot;的映像上载

把一条整型短裤和两条短裤装成一条长的

如何从日志(log)行中删除包名称?

在向WebSphere中的文档添加元素时iText挂起

如何根据配置动态创建N个bean

JFree Chart从图表中删除边框

对角线填充二维数组

嘲笑黄瓜中的对象

在线程Java中调用Interrupt()之后调用Join()

使用MediaPlayer类在一段时间后停止播放音乐

从字节数组切换到JakartaMail org.springframework.mail.javamail.JavaMailSender InputStreamResource

这是JavaFX SceneBuilder的错误吗?

";重复键的值提示唯一约束«;livre_genre_pkey»";例外