| 语言 | 格式 | 评分 |
|---|---|---|
中文(简体) | .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
下载文档到本地,方便使用
文档评分














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