java - Java 元空间 Full GC
问题描述
我对 G1GC 有一些问题。
2400.241: [GC concurrent-root-region-scan-start]
2400.241: [Full GC (Metadata GC Threshold) 2400.252: [GC concurrent-root-region-scan-end, 0.0101404 secs]
2400.252: [GC concurrent-mark-start]
1151M->603M(4356M), 2.6980537 secs]
[Eden: 0.0B(2558.0M)->0.0B(2613.0M) Survivors: 55.0M->0.0B Heap: 1151.7M(4356.0M)->603.6M(4356.0M)], [Metaspace: 259187K->92248K(1034240K)]
[Times: user=3.92 sys=0.00, real=2.70 secs]
这需要很长时间,每 20-30 分钟就会由元空间触发一次完整的 gc。我是这样配置的:
"-XX:MaxMetaspaceSize=768M",
"-XX:MetaspaceSize=256M"
但是每次达到 256M~ 都会触发一次完整的 gc。当它达到第一个高水位线时,下次不应该让它变大直到最大尺寸吗?此外,元空间上的完整 gc 会触发旧 gen 上的完整 gc?我在某处读过它,但我不确定。这使 p99 响应时间比我预期的要高。
解决方案
根据Triggering of gc on Metaspace memory in java 8,需要完整的 GC 以减少元空间的使用。
我的理解是元空间本身并不是垃圾收集的。相反,您在普通堆中拥有对元空间对象的特殊引用的对象。当对象被 GC 收集时,相应的元空间对象被释放。(从概念上讲,它就像终结器正在free
处理元空间对象的终结。)
当它达到第一个高水位线时,下次不应该让它变大直到最大尺寸吗?
显然不是。HotSpot 收集器的正常策略是这样的:
- 分配对象直到达到当前堆限制
- 运行收集器
- 查看回收了多少空间,并在必要时增加(或减少)堆大小。
这里似乎使用了相同的策略。并且完整的 GC 导致足够的元空间被回收,它决定不需要扩展元空间。
对此的创可贴是尝试将-XX:MetaspaceSize
和设置-XX:MaxMetaspaceSize
为相同的值,但这只会降低完整 GC 的频率。
一个真正的解决方案是找出什么在消耗元空间,然后修复它。
推荐阅读
- r - 处理没有 AM/PM 的 Timeseries 数据集并在 R 中转换为 24 小时格式
- reactjs - React TS:使用自定义钩子的测试组件
- javascript - 禁用网页上的键盘快捷键
- php - get_custom_logo 和 get_bloginfo 不起作用
- javascript - Filter Array - 如果数组存在于对象数组中
- javascript - 在 jquery datapicker 重置为当前日期之前捕获手动输入的日期,同时使用 Maxdate 进行限制
- spring-boot - 如何在 Kong 后面配置 Spring OpenAPI UI
- python - Openpyxl 和二分搜索
- gitlab - SonarQube OAuth Gitlab 重定向故障
- aframe - GLTF 不渲染,卡在蓝色加载屏幕