JVM Full GC 频率的问题

2018-04-03 08:55:51 +08:00
 seaswalker

现在遇到了这么一个问题,线上的 JVM minor GC 约 5 分钟一次,老年代比较缓慢的持续增长,需要约 50 天才能增长到 CMS 垃圾回收器的回收阈值比例(70%),也就是说在这期间一次 Full GC 也没有发生。但是由于公司内存的报警是根据物理机内存占用比例触发,目前设置的堆(只是堆,不包括 Metaspace 等)大小占物理内存的 86%,所以这就产生一个我认为比较奇怪的问题: 触发了内存报警,然而实际上一次 Full GC 都没有发生。

我目前想到的优化思路是:

  1. 减少进入老年代的对象的个数,即复用对象。
  2. 提高性能,因为目前来看 CPU 占用率实际很低,进一步提高并发处理的线程数,争取在进入老年代之前完成数据的处理,本质上和 1 的思路一样。
  3. 降低堆和物理内存的比例。

我有些困惑的就是:

  1. 我觉着单纯从 Full GC 的频率来看没有优化的必要,对不对?
  2. 其它的项目也有同样的问题,只不过快速的版本迭代(约 2 天发布一次)将此问题掩盖了,上面报警的项目迭代周期很长。
  3. Full GC 是否应该或者可以完全避免,换句话说,Full GC 没有那么可怕,只要控制在一定的频率、耗时就可以。

菜鸡一枚,没有什么经验,想问问各位大佬的看法。

18780 次点击
所在节点    Java
11 条回复
nl101531
2018-04-03 09:19:08 +08:00
这 gc 很正常啊,频率跟你的服务调用量有关系,是不是服务调用量太小了?
至于触发了内存报警却没有 full gc 这个我也不懂。。。
Robin234
2018-04-03 09:20:01 +08:00
问题不错,Full GC 应该尽量减少,完全避免应该看具体的业务程序,大部分应该还是完全避免不了吧,只要控制在一定的频率就可以,同时 STW 时间不会对业务连接产生超时等错误,就应该 OK。你这个 50 天才产生一次,频率上完全没必要优化。
honeycomb
2018-04-03 09:25:19 +08:00
仅为了避免 full GC 把 CMS 换成 G1 是不是风险太大?
seaswalker
2018-04-03 09:30:27 +08:00
@honeycomb 还没用过 G1
sagaxu
2018-04-03 09:33:18 +08:00
设置 heap 占 86%是不合理的,nonheap 也会占用内存,加起来可能就超过 100%了。
seaswalker
2018-04-03 09:34:37 +08:00
@sagaxu 对,我也这样觉得,而且机器上还有其它进程,加起来超过物理内存了
seaswalker
2018-04-03 09:39:14 +08:00
@nl101531 对,不是那种重要的核心服务。举个例子,物理内存有 8G,80%也就是说达到 6.4GB 时报警,而堆的大小是 7GB,CMS 回收阈值是 70%,假设现在堆的大小是 4GB,不会触发回收,但是 4 + 堆外内存 + 其它进程内存超过了 6.4GB ,就产生了没有 Full GC 却报警的问题
closedevice
2018-04-03 09:43:58 +08:00
调低 heap 所占比例试试
seaswalker
2018-04-03 09:54:56 +08:00
@closedevice 有次打算,😄
ke1e
2018-04-03 09:58:07 +08:00
可以注意下 nonheap 占比
seaswalker
2018-04-03 10:00:23 +08:00
@ke1e 嗯,确实有这个问题

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/443771

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX