Qoder JetBrains 插件 GIF 动画线程死循环导致 IDEA CPU 高占用 — 问题

Qoder JetBrains 插件 GIF 动画线程死循环导致 IDEA CPU 高占用 — 问题上报

状态:待上报 Qoder 团队
记录时间:2026-09-24
严重级别:高(持续占满多核 CPU,影响 IDE 可用性)


一、问题概述

在 IntelliJ IDEA 中使用 Qoder 插件时,IDEA 主进程 CPU 持续占用 118%~130%(多核累加),
风扇狂转、界面卡顿。经线程采样定位,根因为 Qoder 插件的加载动画 GIF(spinner)对应的
Swing ImageIcon 动画线程未被释放
,导致多个 Image Animator 线程在 GIF 逐帧解码上无限循环。

该问题与索引、编译、数据库查询、代码规模均无关,是插件侧的资源泄漏 Bug。


二、环境信息

项目值
操作系统macOS 15.7.7(Intel)
CPU / 内存Intel i7-9750H / 16GB
IDEIntelliJ IDEA 2026.1
插件Qoder JetBrains 插件,版本 2026.923.x(build 75360054)
运行形态Qoder 以 JetBrains 插件形式运行在 IDEA 进程内(PID 68914)

三、现象与观测数据

  • IDEA 进程(PID 68914)CPU 长时间维持在 118%~130%,不随空闲下降。
  • 进程内存在 6 个 名为 Image Animator 0 的线程同时运行。
  • 内存占用约 16%(正常),非 GC / OOM 问题。

四、诊断过程与证据

1. 进程级 CPU 排查

$ ps -Ao pid,%cpu,%mem,comm -r | head
  PID  %CPU %MEM COMM
68914 124.2 16.2 /Applications/IntelliJ IDEA.app/Contents/MacOS/idea

2. 线程采样(sample)定位热点

$ sample 68914 3 -mayDie | grep -cE "Java: Image Animator"
6

6 个线程全部命中 GIF 解码函数:

947 Thread_5413337: Java: Image Animator 0
947 Thread_5413651: Java: Image Animator 0
947 Thread_5413670: Java: Image Animator 0
947 Thread_5413679: Java: Image Animator 0
947 Thread_5413688: Java: Image Animator 0
947 Thread_5413715: Java: Image Animator 0

3. 单个线程完整调用栈(关键证据)

947 Thread_5413337: Java: Image Animator 0
+ 519 JVM_SleepNanos -> JavaThread::sleep_nanos -> PlatformEvent::park_nanos   # 帧间 sleep(GIF 帧延时)
+ 338 Java_sun_awt_image_GifImageDecoder_parseImage (in libawt.dylib)          # 逐帧解码 GIF
      + jni_CallIntMethod -> JavaCalls::call_helper ...
      + jni_GetPrimitiveArrayCritical / jni_ReleasePrimitiveArrayCritical

栈呈现典型的 sleep(帧延时) → parseImage(解码下一帧) → sleep → ... 循环特征,
即 sun.awt.image.GifImageDecoder 在按 GIF 帧率无限循环解码,线程永不退出。


五、根因分析

  1. Qoder 插件在 Swing UI(对话面板的加载/思考动画等)中使用 ImageIcon(gif) 播放动图。
  2. 每个 ImageIcon 的 GIF 动画由 AWT 的 Image Animator 线程驱动,会按帧率持续 sleep + decode 循环。
  3. 当承载动画的组件被隐藏、会话被关闭或面板销毁时,动画线程未被停止(未调用 Image.flush() / 未移除 ImageObserver / 未 dispose),线程发生泄漏。
  4. 泄漏线程随会话/操作次数累积(本次观测到 6 个),每个都独立占满一个逻辑核,最终把多核 CPU 打满。

说明:JDK 8 的 AWT GIF 动画实现(GifImageDecoder)本身即为"只要 ImageObserver 存在就一直循环"的模型,
因此释放责任在插件侧——必须在不再需要动画时主动停止。


六、影响

  • IDE 持续高 CPU,风扇满载、发热、续航骤降。
  • 前台操作(编辑、索引、调试)明显卡顿。
  • 泄漏线程只增不减,不重启 IDE 无法恢复;关闭对话面板/会话后线程依然存在(已验证)。

七、复现路径(推断,供团队验证)

  1. macOS + IntelliJ IDEA 2026.1 + Qoder 插件 2026.923.x。
  2. 进行多次会触发"加载动画"的操作(如多轮对话、多个会话并发请求、反复开关对话面板)。
  3. 观察 Image Animator 线程数随操作累积增加,且关闭会话后不回收。
  4. 用 sample <idea-pid> 3 | grep "Image Animator" 可复现线程泄漏。

八、修复建议(给 Qoder 团队)

  1. 动画生命周期绑定组件:在承载 GIF 的 Swing 组件 removeNotify() / dispose() 时,
    主动停止动画(imageIcon.getImage().flush(),并清空 ImageObserver 引用)。
  2. 统一动画资源管理:加载动画使用单例/共享的动画资源,避免每次请求 new 一个 ImageIcon。
  3. 优先用非 GIF 方案:Swing 加载动画改用 javax.swing.Timer 驱动的多帧 PNG 序列或矢量绘制,
    彻底规避 AWT Image Animator 线程泄漏;或改用 JCEF/HTML 动画。
  4. 会话/请求结束时兜底清理:对话结束、面板关闭、请求取消时,显式停止对应的加载动画。
  5. 增加自检:可加一个内部断言/监控,当 Image Animator 线程数超过阈值时告警,便于回归验证。

九、临时规避方案(用户侧)

  • 重启 IntelliJ IDEA:可立即清除泄漏线程(会丢失当前会话上下文,需先保存工作)。
  • 关闭多余的历史会话标签,减少动画触发次数(对已泄漏线程无效)。
  • 关注并升级到修复该问题的 Qoder 插件新版本。

附:一键排查命令

# 1. 找到 IDEA 进程
ps -Ao pid,%cpu,comm -r | grep -i idea | head

# 2. 统计 Image Animator 泄漏线程数(替换 <PID>)
sample <PID> 3 -mayDie | grep -cE "Java: Image Animator"

# 3. 查看线程栈确认卡在 GIF 解码
sample <PID> 3 -mayDie | grep -A3 "Image Animator"

展开
收起
游客tnoaw6ekqycl6 2026-09-24 11:57:48 25 分享 版权
1 条回答
写回答
取消 提交回答
  • 这报告写得真硬核,简直是教科书级的Bug排查。没点底层功底真写不出来,从ps采样到JNI调用栈,把GifImageDecoder的锅扒得明明白白。Qoder团队要是看到这估计得连夜修,毕竟这种资源泄漏太致命了。

    不过说真的,咱们用户遇到这种“CPU狂转、风扇起飞”的bug确实搞心态,IDE都卡得没法用了。

    建议赶紧把这份文档甩给他们官方反馈,标题就按你改的那个来,清晰有力。

    顺便提醒一句,重启IDE虽然能暂时救急,但别指望它能自动恢复,不重启线程永远在那儿空转。

    希望他们这次能重视,早点出补丁,不然Credits烧完还得搭进去电脑寿命。

    官方详细解决方案:https://help.aliyun.com/zh/lingma/changelogs-jetbrains

    2026-09-25 09:04:22
    赞同 展开评论

Qoder CN 是 Qoder CN 系列中面向软件开发场景的核心子产品(原“通义灵码”),提供 IDE、JetBrains 插件、Visual Studio Code 插件等多种使用形态。Qoder CN 持续提供代码智能生成、智能问答、多文件修改、编程智能体等能力,并在模型选择、专家协作、任务规划等方向全面升级,为开发者带来高效、流畅的编码体验。同时面向企业客户提供企业标准版、企业专属版,具备企业级场景自定义、私域知识增强等能力,助力企业研发智能化升级。

还有其他疑问?
咨询AI助理