zoukankan      html  css  js  c++  java
  • 引用中间件导致的OOM问题调查

    一次使用中间件引发的OOM调查

    描述问题

    在上一次上线完成后,线上的系统在运行几天后就会收到FullGC频繁的告警,而且每台服务都会告警,万能的重启可以解决问题,但不是根本办法,肯定是上一期的代码出现了内存泄漏,在预发环境上,由于操作次数较少,这个问题很难暴露。于是dump 线上的内存,用JProfiler对hprof 文件进行了分析

    分析及解决过程

    分析文件

    使用jprofiler打开 dump文件后,在大对象分析中,发现有个http 请求的封装类有居然有130141个实例,着实把我吓了一跳。

    这个实例在代码中的确是prototype的,但是在引用他的地方,使用spring的注入方式,不会存在依赖无法释放的问题。在AlphaDataRemoteData 类中目前只存在两个注入的变量

    查看Jprofiler实例的引用关系:

    猜想及验证

    可以看到一个FieldValueProcessor 引用了AlphaDataRemoteData这个类,同时也引用了 多例类中注入的@Value;spring的变量注入在populateBean中就会完成,不会生成单独的类,处理注入的value,在看FieldValueProcessor类的包名,猜想应该是引用上次上线引入的中间件导致的问题,引入的中间件的功能是可以在线修改配置变量,不用重启服务就可以生效。该中间件支持spring原生的@Value注入。查看FieldValueProcessor的源码:

    确实引用类bean,而最终的GCRoot中是单例的,他内部存储着一个ConcurrentHashMap来缓存这些需要监听的key和key所属的bean,这是一条强依赖的引用链,无法释放;这个类主要负责用户手动点击后,请求其他系统的,5天10万的数量级在数量上也是匹配的,也说明了为什么ConfigruatorManager为什么占用18M内存的原因

    解决问题

    解决问题的方法时切断引用关系。目前无法移除这个中间件,存在两种改法,

    • 将AlphaDataRemoteData注入的property 移动到一个单例的类中,AlphaDataRemoteData 注入这个类;
    • 将AlphaDataRemoteData修改为单例的,将其内部的成员变量改为外部传入的方式;
      本着修改最小的原则,我们将注入的实例移动到一个单独的配置类中,并在AlphaDataRemoteData中注入了这个类,上到预发环境,解决问题;

    总结

    • 中间件这样实现的原因是为了在从properties解析存储到动态配置解析转换时减少开发,这里缺少一个case将多例的引用不做缓存,直接请求;
    • 在springBoot 使用多例时注意,看是否有会被其他实例长期引用而无法释放,导致OOM;
    • 在新功能上线之前,dump预发环境的内存,看是否存在某个类实例异常多的情况,使用jprofiler 分析一下引用关系,看是否出现了内存泄漏;
    I am chris, and what about you?
  • 相关阅读:
    解决 Mac launchpad 启动台 Gitter 图标无法删除的问题
    React 与 React-Native 使用同一个 meteor 后台
    解决 React-Native mac 运行报错 error Failed to build iOS project. We ran "xcodebuild" command but it exited with error code 65. To debug build logs further, consider building your app with Xcode.app, by ope
    一行命令更新所有 npm 依赖包
    swift学习笔记
    IOS语言总结
    focusSNS学习笔记
    别小看锤子,老罗真的很认真
    windowsphone开发页面跳转到另一个dll中的页面
    【令人振奋】【转】微软潘正磊谈DevOps、Visual Studio 2013新功能、.NET未来
  • 原文地址:https://www.cnblogs.com/arax/p/14857596.html
Copyright © 2011-2022 走看看