搜索

pdf文档 一次线上java 应用响应时间过长问题的排查

247.74 KB 3 页 2 下载 175 浏览 0 评论 0 收藏
所属分类: 后端开发 / Java
语言 格式 评分
中文(简体)
.pdf
3
摘要
本文记录了一次线上Java应用响应时间过长的排查过程。排查发现,问题主要由垃圾回收(Full GC)导致,尤其是CMS垃圾收集器的线程占用了大量CPU资源。进一步分析发现,内存中存在大量未回收的PoolHttpConnectionManager对象,这些对象与OssClient的使用有关。由于OssClient未被显式关闭,导致连接池无法清理,最终占满内存。解决方案是将OssClient改为单例模式,但由于封网期间无法上线,只能通过重启应用来临时解决问题。文档还提到Spring的Controller默认是单例的,这可能对OssClient的行为产生影响。
AI总结
### 总结 这篇文章记录了一次线上 Java 应用响应时间过长问题的排查过程,涉及 CPU、内存、垃圾回收、引用以及 Spring 单例等多个知识点。以下是核心内容的总结: #### 1. 问题描述 - 应用响应时间突然变长,达到 2 秒以上。 - 监控显示 CPU 占用率高达 80%,远超预期(理论上应低于 1%)。 - 垃圾回收日志显示一直在进行 Full GC,但老年代内存几乎满载,GC 效果不佳。 #### 2. 排查过程 - **找出占用 CPU 的线程**:通过 `jstack` 工具发现 CPU 几乎被 CMS 垃圾收集器的线程占用。 - **分析垃圾回收**:Full GC 无法有效回收内存,导致应用响应时间变长。 - **分析 Java 堆内存**:发现内存中存在大量 `PoolHttpConnectionManager` 对象(160 多万个),占用了绝大部分内存。 #### 3. 问题根源 - `PoolHttpConnectionManager` 对象与 OSS 存储客户端的 `OssClient` 有关。 - 源码分析发现:每次 `new OssClient` 时会创建 `PoolHttpConnectionManager`,但只有显式调用 `shutdown` 方法才会清理缓存。 - 这种设计类似于线程池的思想,但因 `OssClient` 隐藏较深,导致内存泄漏。 #### 4. 解决方案 - 将 `OssClient` 改为单例模式,避免频繁创建和释放资源。 - 由于封网期间无法上线,通过重启应用释放内存,问题暂时解决。 #### 5. 其他发现 - Spring 的 Controller 默认是单例的,若在 Controller 中使用成员变量(如 `private OSSClient ossClient`),可能会引发类似问题。 - 单例设计本身没有问题,但需注意成员变量的使用方式。 #### 6. 后记 - 作者提到,看似无用的知识可能在关键时刻发挥作用,体现了持续学习的重要性。 ### 总结 此次排查的核心问题在于内存泄漏和垃圾回收机制失效,导致应用响应时间过长。通过分析 CPU、内存和垃圾回收日志,最终发现是 `OssClient` 的使用问题,并通过改为单例模式解决了问题。
P1
P2
P3
下载文档到本地,方便使用
文档评分
请文明评论,理性发言.