瓜瓜
瓜瓜
发布于 2024-03-02 / 27 阅读
0
0

遇到内存泄漏问题,怎么进行性能问题分析

之前在我们云备份产品的Agent端,为了优化增量备份效率,开发团队设计了设计了以下核心模块:缓存上下文记录模块 / 备份数据写入模块 / 操作日志记录模块等。设计目的是避免重复计算增量位置,但是由于对备份数据写入逻辑中文件流未关闭,导致上线后出现了Agent 机器内存泄漏后备份任务异常中断。

基于以上案例,我将在本文中总结在遇到内存泄漏问题时应该如何分析,并定位问题。

分析方法:控制变量法+排除法

这次问题中我们采用了控制变量法+排除法结合的方式分析出了内存泄漏点。

核心思路:

  • 逐步排除可疑模块,定位泄漏点:通过联合开发人员进行 注释/禁用特定代码逻辑,观察内存是否恢复稳定。若禁用某模块后内存泄漏消失,则该模块为问题根源。以下是详细步骤:

1. 确定怀疑范围

根据业务场景和内存泄漏现象,优先怀疑以下模块:

  • 任务上下文缓存管理(如静态字典ConcurrentDictionary)。

  • M365 API调用(如未释放的HTTP连接、响应流)。

  • 备份数据写入(如文件流未关闭、缓冲区未清理)。

2. 控制变量法实施步骤

步骤①:禁用API调用后的资源处理

  • 操作

    1. 注释M365 API调用后的资源释放逻辑(如关闭响应流)

    2. 重新测试,观察内存变化。

  • 结论

    • 若内存增长加速 → API调用存在资源未释放问题

    • 若内存趋势不变 → 排除此模块。

步骤②:关闭备份数据写入模块

  • 操作

    1. 注释备份数据写入的代码(如文件流操作):

    2. 重新测试,观察内存是否稳定。

  • 结论

    • 若内存泄漏消失 → 文件流未关闭导致泄漏

步骤③:注释缓存逻辑

  1. 注释或删除BackupJobManager.AddContext方法中的缓存写入代码:

  2. 重新编译并部署Agent。

  3. 使用相同测试场景(如高频触发备份任务)运行,观察:

    • 内存是否仍持续增长(通过简单日志或任务管理器观察)。

    • 是否仍抛出OutOfMemoryException

  • 结论

    • 若内存不再增长 → 确认缓存逻辑是泄漏主因

    • 若内存仍增长 → 继续排查其他模块。

3. 修复验证

  • 操作

    1. 修复文件流未正确关闭的逻辑。

    2. 重新运行相同测试场景,确认内存指标稳定。

附:分析方法二:日志分析

核心思路:

  • 通过事务耗时和异常日志定位问题

操作步骤

  1. 添加详细日志

    • 在关键事务(任务上下文缓存管理 / M365 API调用 / 备份数据写入 等)中记录时间戳内存占用耗时异常信息

  2. 复现问题

    • 运行Agent直到内存溢出,分别收集初期后期的日志。

  3. 对比分析

  • 耗时增长:若某事务(如“生成任务上下文”)耗时从50ms逐步增加到500ms,可能因缓存膨胀导致性能下降。

  • 内存日志:若ContextCacheSize字段值持续增加且不回落,直接指向缓存泄漏。

总结

  • 优先使用控制变量法:快速定位问题模块,适合对代码结构较熟悉的场景。

  • 日志分析作为补充:依赖详细日志,适合需要量化分析的场景(如耗时、缓存大小趋势)。

  • 最终验证:无论哪种方法,均需通过修复代码和观察内存指标确认结果。


评论