The Java ZGC garbage collector USES a lot of memory

情到浓时终转凉″ 提交于 2020-12-30 17:17:49

问题


I built a simple application using Springboot.The ZGC garbage collector I use when deploying to a Linux server USES a lot of memory..I tried to limit the maximum heap memory to 500MB with Xmx500m, but the JAVA program still used more than 1GB. When I used the G1 collector, it only used 350MB.I don't know why, is this a BUG of JDK11?Or do I have a problem with my boot parameters? ####Runtime environment

  • operating system: CentOS Linux release 7.8.2003
  • JDK version: jdk11
  • springboot version: v2.3.0.RELEASE Here is my Java startup command
java -Xms128m -Xmx500m \
-XX:+UnlockExperimentalVMOptions -XX:+UseZGC \
-jar app.jar

Here is a screenshot of the memory usage at run time

Heap memory usage https://github.com/JoyfulAndSpeedyMan/assets/blob/master/2020-07-13%20201259.png?raw=true

System memory usage https://github.com/JoyfulAndSpeedyMan/assets/blob/master/2020-07-13%20201357.png?raw=true


Here's what happens when you use the default garbage collector Java startup command

java -Xms128m -Xmx500m \
-jar app.jar

Heap memory usage https://github.com/JoyfulAndSpeedyMan/assets/blob/master/2020-07-13%20202442.png?raw=true

System memory usage https://github.com/JoyfulAndSpeedyMan/assets/blob/master/2020-07-13%20202421.png?raw=true

By default jdk11 USES the G1 garbage collector. Theoretically, shouldn't G1 be more memory intensive than ZGC?Why didn't I use it that way?Did I misunderstand?Since I'm a beginner to the JVM, I don't understand why.


回答1:


ZGC employs a technique known as colored pointers. The idea is to use some free bits in 64-bit pointers into the heap for embedded metadata. However, when dereferencing such pointers, these bits need to be masked, which implies some extra work for the JVM.

To avoid the overhead of masking pointers, ZGC involves multi-mapping technique. Multi-mapping is when multiple ranges of virtual memory are mapped to the same range of physical memory.

ZGC uses 3 views of Java heap ("marked0", "marked1", "remapped"), i.e. 3 different "colors" of heap pointers and 3 virtual memory mappings for the same heap.

As a consequence, the operating system may report 3x larger memory usage. For example, for a 512 MB heap, the reported committed memory may be as large as 1.5 GB, not counting memory besides the heap. Note: multi-mapping affects the reported used memory, but physically the heap will still use 512 MB in RAM. This sometimes leads to a funny effect that RSS of the process looks larger than the amount of physical RAM.

See also:

  • ZGC: A Scalable Low-Latency Garbage Collector by Per Lidén
  • Understanding Low Latency JVM GCs by Jean Philippe Bempel



回答2:


JVM uses much more than just the heap memory - read this excellent answer to understand JVM memory consumption better: Java using much more memory than heap size (or size correctly Docker memory limit)

You'll need to go beyond the heap inspection and use things like Native Memory Tracking to get a clearer picture.

I don't know what's the particular issue with your application, but ZGC is often mentioned as to be good for large heaps. It's also a brand new collector and got many changes recently - I'd upgrade to JDK 14 if you want to use it (see "Change Log" here: https://wiki.openjdk.java.net/display/zgc/Main)




回答3:


This is a result of the throughput-latency-footprint tradeoff. When choosing between these 3 things, you can only pick 2.

ZGC is a concurrent GC with low pause times. Since you don't want to give up throughput, you trade latency and throughput for footprint. So, there is nothing surprising in such high memory consumption.

G1 is not a low-pause collector, so you shift that tradeoff towards footprint and get bigger pause times but win some memory.



来源:https://stackoverflow.com/questions/62926652/the-java-zgc-garbage-collector-uses-a-lot-of-memory

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!