当前位置: 首页 > news >正文

GC/OOM问题处理思路

  1. 原则
    先止损,再分析。如果是灰度阶段,则直接回滚代码,保留一台留作分析;如果是全量阶段个别机器偶发,则禁用该机器。
  2. 流程
    保护现场(禁用机器)-> 拉取堆转储文件以及通过流量监控判断可能的问题接口 -> 堆转储文件分析(使用MAT或JProfiler等工具)-> 结合代码确认问题 -> 修复代码或调整jvm配置(-XX:+HeapDumpOnOutOfMemoryError)并上线 -> 观测上线后机器指标(gc-time、gc-count、olggen-used-percent)
  3. 问题分类
  • GC问题
    • youngGC频繁
      youngGC的正常频率应该是1分钟10次左右。可以考虑增大年轻代的大小
    • fullGC频繁
      fullGC的正常频率应该是一天一次左右。如果发生,一般是存在问题,和oom的处理思路类似。
  • OOM问题
    • stackOverFlow
      无限递归调用,观察异常堆栈日志定位方法

    • java heap space
      大对象或短时间大量对象,通过分析堆转储文件中的类视图(包含类的实例数、自身大小和关联的所有实例大小),定位问题类

    • metaspace
      反射、动态代理等导致动态生成大量类元数据(以反射为例,当同一个反射方法被短时间执行16次,jvm会进行优化,生成对应反射接口的实现类的类元数据并存放到metaspace)。这种问题通过堆转储文件不好定位,因为可能动态生成的类元数据虽然多,但占比不大。一般可以从近期代码变更中是否涉及反射、动态代理进行正向排查。
      解决思路一般是增加反射缓存(比如频繁生成Method的场景,就将Method进行缓存,这样只会生成一次对应的类元数据)、开启类卸载(CMS垃圾回收器)等。

    • GC overhead limit exceeded
      俗称“垃圾回收过头”,即垃圾回收占用了很多CPU时间片,但是回收的内存又很少。一般是内存泄漏(常见类的静态集合属性、threadLocal未执行remove方法),或堆内存较小导致。

  • 实践案例
    • java heap oom
      • 现象
        kds系统在营业高峰出现系统卡顿明显、用户操作响应慢甚至软件闪退的情况。
      • 排查思路
        观测软件日志,寻找耗时较长的接口分析卡顿的原因;通过gc日志排查是否存在频繁gc、full-gc的情况;通过crash日志,查看crash的直接原因以及报错堆栈。
      • 初步排查结果
        营业高峰,系统频繁gc甚至full-gc,导致产生STW现象,所以出现系统卡顿和操作响应慢;至于闪退,主要是因为一些设备性能较差,垃圾回收不过来就oom了。所有的初步原因其实都跟内存吃紧有关,但是通过日志和对应接口代码走读,暂时找不到造成内存吃紧的根因
      • 问题归因思路
        使用性能排查工具JProfiler对系统进程进行问题分析,但该工具运行时会极大占用目标机器的性能,所以可能会影响商家经营,故而决定通过模拟问题商家的经营动作,借助UI自动化测试进行压测,同时使用JProfiler进行性能分析的策略
      • 分析结果
        通过分析堆转储文件,借助JProfiler的类视图工具,识别到一个配置类的实例个数和内存占比很大,再进一步查看该类的引用链路,定位到是一个查询菜品缓存的方法创建了较多该类的实例。
        再结合代码,发现是该方法调用了框架提供的一个缓存查询方法,该方法每次从缓存中查询时都会深拷贝一次数据,从而导致产生大量缓存配置对象。
        至于为什么会深拷贝,是因为框架提供的查询方法被很多模块调用,有些模块查询到配置后会对配置进行修改,所以为了不互相影响,框架侧采取了深拷贝这种比较粗暴的方式
      • 优化方式
        业务侧自己再维护一个菜品配置缓存,读取时不再深拷贝,而直接使用该配置对象
    • metaspace oom
      • 现象
        线上告警metaspace oom导致机器挂掉
      • 排查思路
        先止损,进行机器禁用,避免机器异常信息在注册中心更新不及时导致有新的请求仍然路有到问题机器,同时进行扩容;
        针对问题机器拉取自动dump的堆转储文件,使用美团的线上分析工具进行分析
      • 分析结果
        堆转储文件中发现大量GeneratedMethodAccessorxxx类,xxx是数字,超过了30000个,背景是java反射获取方法时,如果某些方法短时间频繁调用,jvm会进行优化,不再采用反射的方式获取方法,而通过直接生成该方法的代理类(即GeneratedMethodAccessorxxx)的方式,直接调用新生成的代理类的方法,来提高调用效率。这个类较多会导致在metaspace中产生较多的类元数据,从而引发了metaspace内存占用的增长
        另外,gc为什么没有很好地回收新增的类元数据呢?通过查看jvm的启动参数,发现metaspaceSize和MaxMetaspaceSize都是256MB,这导致每次到达最大值才会进行GC,如果该次GC回收效率不高,就有可能导致生产的类元数据不够存放而OOM
      • 解决方案
        对反射频繁调用的Method进行缓存,避免重复生成GeneratedMethodAccessorxxx类。
        同时修改jvm参数,使得MaxMetaspaceSize大于metaspaceSize,给gc预留一些容错空间
http://www.jsqmd.com/news/494489/

相关文章:

  • 提升支付表单转化率:gh_mirrors/ca/card如何通过智能交互设计优化用户体验
  • 终极指南:如何使用Ludwig自动学习率调度优化模型收敛速度
  • JVM常见垃圾回收器总结
  • MusePublic Art Studio多场景落地:插画师/UI设计师/内容创作者通用方案
  • 终极指南:如何使用Theatre高效管理动画素材与Contentful媒体资源
  • 终极指南:Theatre.js性能瓶颈修复完整流程
  • MedGemma X-Ray环境部署:Miniconda3+Torch27+GPU0全栈配置保姆级教程
  • Android Studio使用教程
  • Vuls数据保留策略终极指南:合规要求与存储成本平衡方案
  • wan2.1-vae多风格生成教程:水墨/油画/3D渲染/胶片/像素风参数配置表
  • SiameseAOE中文-base开源可部署:永久免费+保留版权,支持私有化ABSA服务搭建
  • 2026年热门的五金机电公司推荐:五金机电加盟/建筑五金机电服务型公司推荐 - 品牌宣传支持者
  • Open Interpreter JavaScript支持实战:Qwen3-4B实现网页自动化脚本
  • CLIP-GmP-ViT-L-14应用实践:科研论文图表-方法描述自动关联系统
  • Audio Pixel Studio快速上手:无需深度学习基础的轻量级音频AI工作站
  • Kimi-VL-A3B-Thinking商业应用:电商商品图OCR识别与店铺信息提取实战
  • 清音听真部署案例:中小企业如何用Qwen3-ASR-1.7B替代商业ASR服务
  • 张家港昊泰克机械-液压半自动切管机生产厂家,2026优选专业生产厂家 - 栗子测评
  • 2026全自动铝材型切割机源头厂家-张家港昊泰克机械,铝材切割优选 - 栗子测评
  • Alpamayo-R1-10B效果展示:‘Park in the first available spot‘指令的泊车轨迹生成
  • Meixiong Niannian Turbo LoRA效果实测:25步秒出SDXL级高清图
  • MogFace人脸检测镜像快速上手:支持JPG/PNG上传、绿色框标注、实时总数统计
  • DASD-4B-Thinking参数详解:40亿稠密模型如何实现分布对齐序列蒸馏?
  • Face3D.ai Pro算力优化:ResNet50轻量化部署与TensorRT加速实践
  • GTE-Pro保姆级教程:处理超长文本(>512token)的分段向量化策略
  • 通义千问3-VL-Reranker-8B实战教程:多模态检索日志分析与bad case归因
  • Nano-Banana惊艳效果展示:1024×1024高清Knolling图真实案例
  • Phi-3-Mini-128K一文详解:device_map=‘auto‘在多卡环境下的资源分配策略
  • Retinaface+CurricularFace入门指南:人脸特征向量维度与距离度量原理
  • translategemma-4b-it新手指南:三步完成Ollama安装→模型下载→图文提问