使用ZGC启动后无请求仍占用大量cache问题求助
ZGC启动后无请求仍占用大量cache问题排查与解决
环境信息
- 操作系统:Docker
- JDK版本:
openjdk version "17.0.8" 2023-07-18
ZGC配置下的问题现象
启动命令:
CMD ["java","-Xms1g","-Xmx1g","-XX:+UseZGC","-jar","/root/access-1.0.0.jar"]
通过cat /sys/fs/cgroup/memory/memory.stat查看内存状态,发现total_cache占用过高(达1074008064字节,约1GB):
# cat /sys/fs/cgroup/memory/memory.stat cache 1074008064 rss 185012224 rss_huge 67108864 shmem 1073741824 mapped_file 439083008 dirty 12288 writeback 0 swap 0 pgpgin 1096435 pgpgout 807453 pgfault 949371 pgmajfault 2 inactive_anon 1236013056 active_anon 12288 inactive_file 22716416 active_file 229376 unevictable 0 hierarchical_memory_limit 9223372036854771712 hierarchical_memsw_limit 9223372036854771712 total_cache 1074008064 total_rss 185012224 total_rss_huge 67108864 total_shmem 1073741824 total_mapped_file 439083008 total_dirty 12288 total_writeback 0 total_swap 0 total_pgpgin 1096435 total_pgpgout 807453 total_pgfault 949371 total_pgmajfault 2 total_inactive_anon 1236013056 total_active_anon 12288 total_inactive_file 22716416 total_active_file 229376 total_unevictable 0
G1配置下的对比情况
切换为G1垃圾回收器(移除-XX:+UseZGC参数),启动命令:
CMD ["java","-Xms1g","-Xmx1g","-jar","/root/access-1.0.0.jar"]
此时total_cache占用仅为53248字节,恢复正常:
# cat /sys/fs/cgroup/memory/memory.stat cache 53248 rss 620097536 rss_huge 360710144 shmem 0 mapped_file 32768 dirty 45056 writeback 0 swap 0 pgpgin 514950 pgpgout 451431 pgfault 537949 pgmajfault 0 inactive_anon 611667968 active_anon 8192 inactive_file 8093696 active_file 12288 unevictable 0 hierarchical_memory_limit 9223372036854771712 hierarchical_memsw_limit 9223372036854771712 total_cache 53248 total_rss 620081152 total_rss_huge 360710144 total_shmem 0 total_mapped_file 32768 total_dirty 45056 total_writeback 0 total_swap 0 total_pgpgin 514944 total_pgpgout 451431 total_pgfault 537942 total_pgmajfault 0 total_inactive_anon 611627008 total_active_anon 8192 total_inactive_file 8093696 total_active_file 12288 total_unevictable 0
需求
需降低ZGC模式下的total_cache占用,避免监控判定Pod内存过高导致重启。
解决方法
1. 禁用ZGC大页内存
ZGC默认使用大页内存,可能导致cache占用偏高。添加JVM参数禁用大页:
CMD ["java","-Xms1g","-Xmx1g","-XX:+UseZGC","-XX:-UseLargePages","-jar","/root/access-1.0.0.jar"]
也可根据系统支持情况指定页大小,例如-XX:LargePageSizeInBytes=2m。
2. 调整ZGC内存预留参数
限制ZGC物理内存上限或调整回收间隔:
-XX:ZPhysicalMemoryMax=900m:限制ZGC可使用的物理内存-XX:ZCollectionInterval=30:设置30秒的垃圾回收间隔,更频繁地释放空闲内存
3. 匹配容器与JVM内存配置
用百分比参数替代固定内存值,让JVM根据容器内存自动适配:
CMD ["java","-XX:MaxRAMPercentage=80","-XX:+UseZGC","-jar","/root/access-1.0.0.jar"]
同时确保容器内存略大于JVM最大内存,避免ZGC因内存压力过度使用缓存。
4. 升级JDK版本
JDK 17后续版本(如17.0.10+)对ZGC的内存缓存占用有优化,尝试升级到最新17 LTS版本。
5. 临时清理文件缓存
在容器启动脚本中添加缓存清理命令(需容器具备权限):
echo 3 > /proc/sys/vm/drop_caches
该操作仅能临时缓解,无法从根本解决问题。
内容的提问来源于stack exchange,提问作者Eda
相关产品推荐
相关产品推荐

