利用JProfiler对应用服务器内存泄漏问题诊断一例_第1页
利用JProfiler对应用服务器内存泄漏问题诊断一例_第2页
利用JProfiler对应用服务器内存泄漏问题诊断一例_第3页
利用JProfiler对应用服务器内存泄漏问题诊断一例_第4页
利用JProfiler对应用服务器内存泄漏问题诊断一例_第5页
已阅读5页,还剩9页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

利用 JProfiler 对应用服务器内存泄漏问题诊断一例 曾胜财 IBM BCS 部门 I T 架构师 2005 年 9 月 在中间件应用服务器的整体调优中 有关于等待队列 执行线程 EJB 池以及数据库连接池和 Statement Cache 方面的调优 这些都属于系统参数方面的调优 本文主要从另外一个角度 也 就是从应用的角度来解决中间件应用服务器的内存泄露问题 从这个角度来提高系统的稳定性和性 能 项目背景 问题描述问题描述 某个大型项目 Use Case 用例超过 300 个 在项目上线后 其 Web 应用服务器经常宕机 表 现为 1 应用服务器内存长期不合理占用 内存经常处于高位占用 很难回收到低位 2 应用服务器极为不稳定 几乎每两天重新启动一次 有时甚至每天重新启动一次 3 应用服务器经常做 Full GC Garbage Collection 而且时间很长 大约需要 30 40 秒 应用 服务器在做 Full GC 的时候是不响应客户的交易请求的 非常影响系统性能 Web 应用服务器的物理部署应用服务器的物理部署 一台 Unix 服务器 4CPU 8G Memory 来部署本 Web 应用程序 Web 应用程序部署在中 间件应用服务器上 部署了一个节点 Node 只配置一个应用服务器实例 Instance 没有 做 Cluster 部署 Web 应用服务器启动脚本中的内存参数应用服务器启动脚本中的内存参数 MEM ARGS XX MaxPermSize 128m XX MaxNewSize 512m Xms3096m Xmx3096m XX PrintGCDetails Xloggc inwebapp1 gc 可以看出目前生产系统中 Web 应用服务器的内存分配为 3G Memory Web 应用服务器的重要部署参数应用服务器的重要部署参数 参数名称 参数值 参数解释 kernel default Thread Count 120 执行线程数目 是并发处理能力的重要参数 Session Timeout 240 分钟 4 小时 HttpSession 会话超时 分析分析 分析方法分析方法 内存长期占用并导致系统不稳定一般有两种可能 1 对象被大量创建而且被缓存 在旧的对象释放前又有大量新的对象被创建使得内存长期高位占用 表现为 内存不断被消耗 在高位时也很难回归到低位 有大量的对象在不断的创建 经 过很长时间后又被回收 例如 在 HttpSession 中保存了大量的分页查询数据 而 HttpSession 的会话超时时间设置过长 例如 1 天 那么在旧的对象释放前又有大量新的对 象在第二天产生 解决办法 对共享的对象可以采用池机制进行缓存 避免各自创建 缓存的临时对象应该 及时释放 另一种办法是扩大系统的内存容量 2 另一种情况就是内存泄漏问题 表现为 内存回收低位点不断升高 以每次内存回收的最低点连成一条直线 那么它是一 条上升线 内存回收的频率也越来越高 内存占用也越来越高 最终出现 Out of Memory Exception 的系统异常 解决办法 定位那些有内存泄漏的类或对象并修改完善这些类以避免内存泄漏 方法是 经过一段时间的测试 监控 如果某个类的对象数目屡创新高 即使在 JVM Full GC 后仍然数目 降不下来 这些对象基本上是属于内存泄漏的对象了 问题定位问题定位 这里请看 5 月份 Web 应用服务器的内存回收图形 注意 5 月 18 日早上 10 点重新启动了 Web 服务器 5 月 20 日早上又重新启动了 Web 服务器 在 Web 应用重要部署参数中 我们知道 Session 的超时时间为 4 个小时 我们在监控 平台也观测到 在 18 日晚上 10 点左右所有的会话都过期了 从图形一中也能看出 18 日晚上确 实系统的内存有回收到 40 就象股票的高位跳水 从图形一 5 月 18 日 中我们也能看到 Full GC 回收后的内存占用率走势 红色曲线 上午基本平滑上升到 20 内存占用率 中午开始上升到 30 下午上升到 40 从图形二 5 月 19 日 中我们也能看到 Full GC 回收后的内存占用率走势 红色曲线 上午又上升到了 60 到下午上升到了 70 从黄色曲线 GC 花费的时间 以秒为单位 Full GC 的频率也在增快 时间耗费也越来 越长 在图形一中基本高位在 20 秒左右 到 19 日基本都是 30 40 秒之间了 图形一图形一 5 月月 18 日日 图二图二 通过上述分析 我们基本定位到了 Web 应用服务器的内存在高位长期占用的原因了 是内存泄露 并且正是由于这个原因导致系统不稳定 响应客户请求越来越慢的 解决方法解决方法 方法如下 我们从图形二中发现 在 8 95 将近 9 点钟 到 9 66 将近 9 点 40 期间有几次 Full GC 但是有内存泄漏 从占用率 40 上升到 50 左右 泄漏了大约 10 的内存 约 300M 我们在自己搭建的 Web 应用服务器平台 应用软件版本和生产版本一致 做这一阶段相同 的查询交易 表明对同一个黑盒 Web 应用 施加同样的刺激 相同的操作过程和查询交易 以期重现现象 我们使用 Jprofiler 工具对 Web 应用服务器的内存进行实时监控 做完这些交易后 用户退出系统 并等待 Web 应用服务器的 HttpSession 超时 我们这 里设置为 15 分钟 我们对 Web 应用服务器做了两次强制性的内存回收操作 发现如下 图三图三 如图三所示 内存经过 HttpSession 超时后 并强制 gc 后 仍然有大量的对象没有释放 例如 m security MenuNode 仍然有 807 个实例没有释放 我们继续追溯发现 这些 MenuNode 首先存放在一个 ArrayList 对象中 然后发现这个 ArrayList 对象又是存放在 WHsessionAttrVO 对象的 Map 中 WHsessionAttrVO 对象又是存放在 ExternalSessionManager 的 staic Map 中 名称为 sessionMap 如图四所示 图四图四 我们发现 m WHsessionAttrVO 中保存了 EJBSessionId 信息 登录用户的唯一标志 由用户 id 登录时间戳组成 每天都不同 和一个 HashMap 这个 HashMap 中的内容有 ArrayList 内有 MenuTreeNodes 菜单树节点 HashMap 内有操作人员代码信息 CurrentVersion 当前版本号 CurrentTime 当前系统时间 WHsessionAttrVO 这个对象的最终存放在 ExternalSessionManager 的 static Map sessionMap 中 由于 ExternalSessionManager 是一个全局的单实例 不会释放 所以它的成 员变量 sessionMap 中的数据也不会释放 而 Map 中的 Key 值为 EJBSessionId 每天登录的用 户 EJBSessionId 都不同 就造成了每天的登录信息 包括菜单信息 都保存在 sessionMap 中不 会被释放 最终造成了内存的泄漏 图五图五 如上图所示 WHsessionAttrsVO 对象中除了有一个 String 对象 内容是 EJBSessionId 还 有一个 HashMap 对象 图六图六 如上图所示 这个 HashMap 中的内容主要有 menuTreeNodes 为 key value 为 ArrayList 的对 象和以 czrydminfo 为 key value 为 HashMap 对象的数据 图七图七 如上图所示 menuTreeNodes 为 key value 为 ArrayList 对象中包含的对象有许多的 MenuNode 对象 封装的都是用户的菜单节点 图八图八 如上图所示 最顶层 Root 的初始对象为一个 ExternalSessionManager 对象 其中的一个成 员变量为 static 静态的 名称为 sessionMap 这个对象是 singleton 方式的 全局只有一个 初步估量初步估量 我们从图形一和图形二中可以看出 每天应用服务器损失大约 40 的内存 大约 1G 左右 从图形四可以看出 当前用户 Id 有 807 个菜单项 每个菜单项为一个 MenuNode 对象实例 图形四中的这个实例的 size 为 592 Byte 这些菜单数据和用户基本登录信息 czrydmInfo HashMap 也都存放在 WHsessionAttrVO 对象中 当前这个 WHsessionAttrVO 对象的 size 为 457K 我们做如下估算 假设平均每天有 4 千人 估计值 这个数值仅仅是 5 月 19 日峰值的 1 2 左右 登录系统 有重复 登录的现象 例如 上午登录一次 中午退出系统 下午登录一次 以平均每人占用 200K 估 计值 是用户 id 的 Size 的 1 2 左右 来计算 一天泄漏的内存约 800M 比较符合目前内存泄 漏的情况 当然 这种估计仍然需要经过实践的检验 方法是 当这次发现的内存泄漏问题解决后 看系统是否还有其它内存泄漏问题 方案 ExternalSessionManager 类是当初某某软件商设计的用来解决 Web 服务器负载均衡的模块 这 个类主要用来保存客户的基本登录信息 包括会话的 EJBSessionId 以维护多个 Web 服务器之 间的会话信息一致 改进方案有两种 回页首回页首 从架构设计方面改进 实现 Web 层的负载均衡有很多标准的实现方式 例如 采用负载均衡设备 硬件或软件 来实现 如果采用新的 Web 层的负载均衡方式 那么就可以去掉 ExternalSessionManager 这个类了 从应用实现方面改进 保留当前的 Web 层的负载均衡设计机制 仅仅从应用实现方面解决内存泄漏问题 首先菜单信 息不应该保存在 ExternalSessionManager 中 其次 增加对 ExternalSessionManager 类 中用户会话登录信息的清除 有几种方式可以选择 被动方式 当 HttpSession 会话超时 或过期 被 Web 应用服务器回收时清除 相应的 ExternalSessionManager 中的过期会话登录信息 主动方式 可以采用任务定时清理每天的过期会话登录信息或线程轮询清理 采用新的会话登录信息存储方式 ExternalSessionManager 的 sessionMap 中 的 key 值不再以 EJBSessionId 作为键值 而是以用户 id EJBSessionId 的前 11 位 代 替 由于用户 id 每天都是一样的 所以不会造成内存泄漏 保存得登录信息也不再包含菜单 节点信息 而只是登录基本信息 最多也只是保存整个系统所有的用户 id 及其基本登录信息 大约每个用户的登录信息只有 1 5K 左右 而目前这个系统的营业网点用户为 1 万左右 所 以大约只占用 Web 服务器 15M 内存 实施情况 采用的方案 某某软件商采用了新的会话登录信息存贮方案 即 ExternalSessionManager 的成 员变量 sessionMap 中不再保存用户菜单信息 只保存基本的登录信息 存储方式采用用户 id 11 位 作为键值 key 来保留用户基本登录信息 基本分析 由于基本登录信息只有 1K 左右 而目前内网登录的用户总数也只有 8887 个 所以只 保存了大约 10M 15M 的信息在内存 占用量很小 并且不会有内存泄漏 用户菜单信息保存在 session 中 如果用户退出时点击 logout 页面 那么应用服务器可以很快地释放这部分内存 如果 用户直接关闭窗口 那么保存在 session 中的菜单信息只有等会话超时后才会由系统清除并回收内 存 监控状况 回页首回页首 图九图九 如图九所示 ExternalSessionManager 中只保留了简单的登录信息 Map 中保存了 WHsessionAttrVO 对象 包括 当前版本 currentversion 操作人员代码基本信息 czrydmInfo 当前时间 currenttime 图十图十 如图十所示 这个登录用户的基本信息只有 1368 bytes 大约 1 3K 图十一图十一 如图十一所示 一共有两个用户 相同的用户 id 登录系统 当一个用户使用 logout 页面退出时 保留在 session 中的菜单信息 MenuNode 立刻释放了 所以 Difference 一栏减少了 806 个菜单 项 图十二图十二 如图十二所示 当另外一个会话超时后 应用服务器回收了整个会话的菜单信息 MenuNode 图上已经没有 MenuNode 对象了 并且由于是同一个用户登录 所以保留在 ExternalSessionManager 成员变量 sessionMap 中的对象 WHsessionAttrVO 只有一个 id 而没有产生多个 没有因为多次登录而产生多个对象的后果 避免了内存泄漏问题的出现 解决了 前期定位的内存泄漏问题 图十三图十三 如图十三所示 经过 gc 内存回收后 发现内存回收比较稳定 基本都回收到了最低点 也证明了内 存没有泄露 结论与建议 从测试情况看 解决了前期定位的内存泄漏问题 生产系统实施后的监控与分析生产系统实施后的监控与分析 经过调优后 我们发现 在 2005 年 6 月 2 日晚 9 点 40 左右重新部署 启动了 Web 应用服务器 采用了新的调优方案 经过几天的监控运行 发现 Web 应用服务器目前运行基本稳定 目前没 有出现新的内存泄漏问题 下列图示说明了这一点 图十四图十四 2005 年年 6 月月 2 日日 如图十四所示 6 月 2 日晚 21 7 21 点 42 分 重新启动应用服务器 内存占用很少 大约为 15 请看红色曲线 每次 GC 消耗的时间也很短 大约在 5 秒以内 请看黄色曲线 图十五图十五 2005 年年 6 月月 3 日周五日周五 如图十五所示 在 6 月 3 日周五的整个工作日内 内存的回收基本到位 回收位置控制在 20 30 之 间 也就是在 600M 900M 之间 请看红色曲线的最低点 始终可以回收 2G 的内存供应用程序 使用 每次 GC 的时间最高不超过 20 秒 Full GC 平均在 10 秒左右 时间消耗比较短 请看黄色 曲线 图十六图十六 2005 年年 6 月月 5 日周日日周日 如图十六所示 在周日休息日期间 Web 应用服务器全天只做了大约 4 次 Full GC 黄色曲线中的 小山峰 时间都在 10 秒以内 大的 Full GC 后 内存只占用 10 内存回收很彻底 图十七图十七 2005 年年 6 月月 6 日周一日周一 如图十七所示 在周一工作日期间 内存回收还是不错的 基本可以回收到 30 见红色曲线的最

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论