JVM深度学习系列之实践经验(七)

  1. 如何充分利用高性能服务器(比如:内存16G)
    1. 一般的思路是调大堆内存(12G) 但是同时会引起几个问题
      1. 年轻代GC和老年代GC的时间就会很长,严重的10多s,这样会导致系统不定时的卡顿(GC的stop the world),用户不能操作。
      2. 当发生堆溢出时,无法dump堆 一般快照文件达到十几G,即使dump下来,也很难分析
    2. 解决:
      1. 建立逻辑集群
        1. 在一台机器上,开启多个服务器,修改端口号,每个服务器分配2G内存,然后前端使用nginx均衡分发
      2. 不建立集群 将full GC 调至最低,最好可以一天执行一次,然后在午夜手动触发。
  2. 线上老年代一直在慢速增长(真实线上问题) 由于是同事的系统的问题,在此只能尽量用文字描述,不足之处,请读者谅解。
    1. 起源:内存堆使用率超过80%后报警
    2. 处理:
      1. 先通过jinfo 查看当前虚拟机配置 发现是由虚拟机自动动态调节老年代新生代大小比例。GC策略使用的是Paraller Scavenge 以系统吞吐量优先的多线程垃圾回收器。(刚开始觉得这种配置不合理,一般在面向用户时使用并发CMS收集器,平缓GC,后来发现由于是专门用来跑work的服务器,这种配置也是合适的)
      2. 通过jstat -gcutil PID 1000 每1秒打印堆使用情况日志 发现在一次young GC后老年代增长0.16%  年轻代的大部分空间也被回收 于是就想要知道到哪些对象晋升到老年代 
      3. 通过jmap dump一次GC前后的两份快照
      4. 通过jvisual VM 分析大对象 发现晋升的对象只有两个 都是netty对象。从快照看一切正常。 (一般问题到这就能看出来)
      5. 后来发现是由于虚拟机动态调节策略,而且是以吞吐量为优先(以空间换时间,以减小新生代大小从而降低新生代回收时间,保证吞吐率)的垃圾回收策略,导致新生代大小特别小(在报警时存活区大小只有2M),部分对象就会直接进入老年代。
      6. 将动态调节修改为指定新生代大小 将垃圾回收策略改为ParNew策略 程序回复正常。

以上内容,欢迎拍砖!

猜你喜欢

转载自blog.csdn.net/qq_29857681/article/details/86136961
今日推荐