内存泄漏的代价是巨大的,并且通常直接与生产停机时间或部署进度表延迟有关。 不幸的是,适当的测试解决方案的成本也很高,而且客户通常不愿意-或无法-投资必要的资源。
需要明确的是,解决内存泄漏的最佳方法是在测试中检测并解决它们。 理想情况下,应该有一个测试计划,一个与生产环境相同的测试环境,该环境可以驱动代表性的和异常的工作负载,以及具有专门用于系统测试的技能的技术资源。 这是确保尽可能向生产过渡的最佳方法。 但是,设计和提供这种环境以及相关的文化变化并不是本文的重点。
Java有四种常见的内存使用问题:
- Java堆内存泄漏
- 堆碎片
- 内存资源不足
- 本机内存泄漏。
WebSphere Application Server引入了两种补充技术来帮助客户解决Java堆内存泄漏(在一定程度上,这些工具还解决了由内存资源不足引起的问题;本文未解决这两个问题的相似性)。
通常,当应用程序无意(由于程序逻辑错误)保留对不再需要的对象的引用时,将导致Java堆内存泄漏。 这些无意的对象引用可防止内置的Java垃圾回收机制释放这些对象使用的内存。 这些内存泄漏的常见原因是:
- 插入而不删除到集合中
- 无限缓存
- 未调用的侦听器方法
- 无限循环
- 会话对象过多
- 编写得不好的自定义数据结构。
由于配置问题或系统容量问题,可能导致由于内存资源不足而导致的内存使用问题。 例如,可以使用-Xmx参数将Java虚拟机允许的最大堆大小配置为一个太低的值,以致无法容纳内存中的用户会话总数。 或者,系统的物理内存可能太少,无法容纳当前的工作负载。 本机内存泄漏是非Java代码中的内存泄漏。 例如,在Type-II JDBC驱动程序中,或者在Java进程地址空间的非堆段中出现碎片。
这是一篇介绍性文章,专为Java开发人员,系统管理员和问题确定顾问使用在IBM WebSphere Application Server上部署的应用程序而设计。
检测内存泄漏根本原因的现有技术存在问题
有许多问题会导致内存泄漏,这对于系统管理员来说尤其麻烦:
传统的Java内存泄漏根本原因检测技术具有很大的性能负担,可能不适合在生产环境中使用。 这些技术通常包括堆转储分析,附加JVMPI(Java虚拟机分析器接口)或JVMTI(Java虚拟机工具接口)代理,或使用字节码插入来跟踪集合中的插入和删除。
传统的冗余方法(例如群集)只能在一定程度上提供帮助。 内存泄漏将在整个群集成员中传播。 受影响的应用服务器的响应速度会减慢工作负载管理技术。 这可能导致将请求路由到更健康的服务器,并导致协调的应用程序服务器崩溃。
典型的分析解决方案应尝试将应用程序移动到隔离的测试环境中,在该环境中可以重新创建问题,并且可以执行分析而不会影响生产服务器。 在这些测试环境中,复制内存的困难使关联的内存泄漏的成本增加了。
这些问题的原因是传统技术试图同时进行检测和分析。
WebSphere解决方案
WebSphere Application Server V6.0.2和更高版本提供了一个分为两个阶段的解决方案,该解决方案将检测问题与分析分开。
第一步是在生产WebSphere Application Server运行时中运行的轻量级内存泄漏检测机制。 这种轻量级的检测技术使用便宜的,通用的Java堆使用情况统计信息来监视内存使用情况趋势,并提早通知内存泄漏。 这使管理员有时间准备适当的备份解决方案,并以脱机方式分析问题的根