我们正在将 java 8 应用程序迁移到 java 17,并将 GC 从G1GC
to ZGC
。我们的应用程序作为容器运行,这两个基础映像之间的唯一区别是 java 的版本。例如对于 java 17 版本:
FROM ubuntu:20.04
...
ENV JAVA_HOME /usr/lib/jvm/jdk-17.0.5
ENV PATH $JAVA_HOME/bin:$PATH
及其相关的java选项:
-Xmx100g
-XX:+UseZGC
运行应用程序时,会出现以下 gc 警告:
[0.018s][warning][gc] ***** WARNING! INCORRECT SYSTEM CONFIGURATION DETECTED! *****
[0.018s][warning][gc] The system limit on number of memory mappings per process might be too low for the given
[0.018s][warning][gc] max Java heap size (102400M). Please adjust /proc/sys/vm/max_map_count to allow for at
[0.018s][warning][gc] least 184320 mappings (current limit is 65530). Continuing execution with the current
[0.018s][warning][gc] limit could lead to a premature OutOfMemoryError being thrown, due to failure to map memory.
几个小时后,当内存达到大约~60GB
,应用程序崩溃:
Java HotSpot(TM) 64-Bit Server VM warning: INFO: os::commit_memory(...) failed; error='Not enough space' (errno=12)
Java HotSpot(TM) 64-Bit Server VM warning: INFO: os::commit_memory(...) failed; error='Not enough space' (errno=12)
# fatal error: Failed to map memory (Not enough space)
# A fatal error has been detected by the Java Runtime Environment:
[error occurred during error reporting (), id 0xb, SIGSEGV (0xb) at pc=0x00007fc929746941]
但我们的java 8版本的应用程序以前从未遇到过这样的问题。我知道调整vm.max_map_count
很可能会解决问题”,但我的问题是 java 或 GC 中究竟发生了什么变化,导致了这些警告并最终导致了这些错误?
但我的问题是 java 或 GC 中到底发生了什么变化导致这些警告并最终导致这些错误?
它只是 ZGC 垃圾收集器的实现细节。它需要对其内存映射进行更细粒度的控制,这意味着映射总量更大。
较旧的收集器通常会保留巨大的连续地址空间空间,并且很少在这些范围中打一些孔以将内存释放回操作系统。 ZGC 适用于不同大小的非连续范围,这意味着它必须向操作系统请求更多单独的映射。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)