一次线上java 应用响应时间过长问题的排查
247.74 KB
3 页
0 评论
语言 | 格式 | 评分 |
---|---|---|
中文(简体) | .pdf | 3 |
摘要 | ||
文档记录了一个线上Java应用响应时间过长问题的排查过程。接到报警后,发现CPU占用异常高,通过分析线程堆栈和垃圾回收日志,发现CMS垃圾收集器线程占用了大量CPU。此外,Full GC频繁发生但效果不佳,老年代内存几乎满了。进一步分析Java堆内存,发现160多万个PoolHttpConnectionManager对象占用了大部分内存。这源于每次使用OSS客户端时都new OssClient,导致PoolHttpConnectionManager被缓存,无法回收。解决方案是将OssClient改为单例,避免频繁创建。 | ||
AI总结 | ||
### 《一次线上Java应用响应时间过长问题的排查》总结
#### 问题背景
一个老Java应用接到响应时间过长的报警,单机QPS仅10左右,却出现响应时间达到2秒以上的情况,且CPU占用异常高达80%。通过排查发现,问题主要涉及CPU、内存、垃圾回收、引用、Spring和单例等知识,最终定位为内存泄漏导致的性能问题。
---
#### 问题排查
1. **监控与初步分析**
- 报警触发:服务响应时间过长,达到2秒以上。
- 监控显示CPU占用高达80%,与预期不符。
2. **CPU占用分析**
- 通过`top`命令发现Java应用占用CPU过高。
- 使用`ps`和`jstack`命令定位到占用CPU的线程,发现是CMS垃圾收集器线程。
3. **垃圾回收问题**
- 垃圾回收日志显示频繁发生Full GC,但回收效果甚微,老年代内存几乎满。
- 开始怀疑内存泄漏或对象回收不及时。
4. **内存分析**
- 将线上流量切走,dump堆内存后发现,堆内存中存在160多万个`PoolHttpConnectionManager`对象,占用了绝大部分内存。
- 猜测与OSS客户端相关,因每次使用OSS时都会新建`OssClient`且未正确释放。
5. **OSS客户端源码分析**
- `OssClient`在创建时会新建`PoolHttpConnectionManager`,但源码中隐藏了对其的缓存,导致每次新建的`PoolHttpConnectionManager`无法被垃圾回收。
- 只有显式调用`shutdown`方法才能释放资源。
6. **问题根源**
- 每次使用OSS时都新建`OssClient`,未调用`shutdown`,导致内存泄漏。
- Spring的`Controller`是单例,但在某些情况下未正确管理资源。
---
#### 解决方案
- 将`OssClient`改为单例,避免每次都新建实例。
- 在生产环境中,由于封网期间无法上线代码,临时通过重启应用解决问题。
- 后续建议在代码中正确使用单例模式,并确保调用`shutdown`释放资源。
---
#### 总结
通过imiter this issue,发现老旧系统中可能隐藏的资源泄漏问题,及时重视监控和性能调优尤为重要。同时,熟悉框架的使用规则和源码设计思想能够帮助快速定位问题。 |
P1
P2
P3
下载文档到本地,方便使用
文档评分