我使用部署到Linux服务器时使用的Springboot.The ZGC垃圾收集器构建了一个简单的应用程序,它使用大量内存,我试图用Xmx500m将最大堆内存限制在500 1GB以内,但是Xmx500m程序仍然使用超过1GB的内存。当我使用G1收集器时,它只使用350 my。我不知道为什么,这是JDK11 11的错误吗?还是我的引导参数有问题?####Runtime环境
java -Xms128m -Xmx500m \
-XX:+UnlockExperimentalVMOptions -XX:+UseZGC \
-jar app.jar这里是运行时内存使用情况的屏幕截图
堆内存使用https://github.com/JoyfulAndSpeedyMan/assets/blob/master/2020-07-13%20201259.png?raw=true
系统内存使用https://github.com/JoyfulAndSpeedyMan/assets/blob/master/2020-07-13%20201357.png?raw=true
下面是使用默认垃圾收集器启动命令时发生的情况
java -Xms128m -Xmx500m \
-jar app.jar堆内存使用https://github.com/JoyfulAndSpeedyMan/assets/blob/master/2020-07-13%20202442.png?raw=true
系统内存使用https://github.com/JoyfulAndSpeedyMan/assets/blob/master/2020-07-13%20202421.png?raw=true
默认情况下,jdk11使用G1垃圾收集器。理论上,G1不应该比ZGC更需要内存吗?为什么我不这样使用它?我是不是误解了?因为我是JVM的初学者,所以我不明白为什么。
发布于 2020-07-16 11:49:21
ZGC使用了一种称为有色指针的技术。其想法是使用64位指针中的一些空闲位到堆中,用于嵌入元数据。但是,当取消引用这些指针时,需要屏蔽这些比特,这意味着JVM需要做一些额外的工作。
为了避免掩蔽指针的开销,ZGC采用了多映射技术.多映射是指将多个虚拟内存范围映射到相同范围的物理内存。
ZGC使用Java堆的3个视图("marked0“、"marked1”、"remapped"),即堆指针的3种不同“颜色”和同一个堆的3个虚拟内存映射。
因此,操作系统可能报告更大的内存使用量3倍。例如,对于512 MB堆,报告的提交内存可能高达1.5GB,不包括内存除了堆。注意:多映射会影响所报告的已使用内存,但在物理上堆仍将在RAM中使用512 MB。这有时会导致一个有趣的效果,即进程的RSS看起来像大于物理RAM的数量。
另请参阅:
发布于 2020-07-16 03:43:20
JVM使用的不仅仅是堆内存,更好地理解JVM内存消耗:Java使用比堆大小更多的内存(或大小正确的Docker内存限制)。
您需要超越堆检查,使用本机内存跟踪这样的东西来获得更清晰的画面。
我不知道您的应用程序有什么特别的问题,但是经常提到ZGC对大堆很好。它也是一个全新的收集器,最近做了很多修改--如果你想使用它,我会升级到JDK 14 (参见这里的“变更日志”:https://wiki.openjdk.java.net/display/zgc/Main)
发布于 2020-07-16 04:18:50
这是throughput-latency-footprint权衡的结果。当你在这三件事中做出选择时,你只能选择2件。
ZGC是一个具有低暂停时间的并发GC。由于您不想放弃吞吐量,所以您可以用延迟和吞吐量来换取内存占用。因此,如此高的内存消耗是不足为奇的。
G1不是一个低暂停的收集器,所以您可以将这种权衡转向占用空间,获得更大的暂停时间,但会赢得一些内存。
https://stackoverflow.com/questions/62926652
复制相似问题