Tuesday, January 13, 2009

Java内存泄露原因

更多精彩请到 http://www.139ya.com


内存泄漏的成本非常高昂,经常伴随着产品停机时间和零碎的部署安排。遗憾的是,合适测试解决方案的成本也十分高昂,客户经常不愿意或者不能对必要的资源进行投资。
为了更加清楚起见,解决内存泄漏的最佳方法是在测试时检测并解决它们。理想情况下,应当进行测试安排,并且有一种与产品环境完全相同的测试环境,这种环境能够驱动典型的和异常的工作负载,还应当有技术资源,他们具备专门进行系统测试的适当技能。这是尽可能确保完全转换到产品的最佳方式。但是,设计和提供这样一种环境,以及相关的文化变化,都不是本文的重点。
Java 中有四类常见的内存使用问题:

* Java 堆内存泄漏
* 堆碎片
* 内存资源不足
* 本机内存泄漏。


一般来说,当应用程序(由于程序逻辑错误)无意中保存对于不再需要的对象的引用时,会导致 Java 堆内存泄漏。这种无意对象引用阻止内置 Java 垃圾回收机制释放由这些对象所使用的内存。这些内存泄漏的共同原因是:

* 向集合中插入而没有删除
* 未绑定的缓存
* 未调用的侦听器方法
* 无限循环
* 过多的会话对象
* 编写不佳的自定义数据结构。

由于内存资源不足而产生的内存使用问题可能是由于配置问题或系统容量问题所导致的。例如,在为 Java 虚拟机配置最大允许堆大小时所使用的 -Xmx 参数值过低,不能容纳内存中的用户会话总数。或者,系统的物理内存过少,不能容纳当前工作负载。本机内存泄漏是非 Java 代码中的内存泄漏;例如,在 Type-II JDBC 驱动程序或者 Java 进程的地址空间中的非堆段内的碎片。
这是一篇为 Java 开发人员、系统管理员以及问题确定顾问撰写的介绍性文章,这些人员使用部署在 IBM WebSphere Application Server 上的应用程序。
用于检测内存泄漏根源的现有技术中所存在的问题
有大量导致内存泄漏的问题,它们对于系统管理员特别棘手:

* 传统的 Java 内存泄漏根源检测技术有十分显著的性能负担,可能不适于在生产环境中使用。这些技术通常包括堆转储分析、附加 Java 虚拟机分析器接口(Java Virtual Machine Tools Interface,JVMPI)或Java 虚拟机工具接口(Java Virtual Machine Tools Interface,JVMTI)代理,或者使用字节代码插入来跟踪向集合中的插入和删除。
* 传统的冗余方法,例如群集技术,只能在一定程度上有所帮助。内存泄漏将在群集成员中传播。受影响的应用服务器的响应速度减缓了负载管理技术。这可能导致将请求路由到运行状况更好的服务器,从而导致协调应用服务器崩溃。

一种典型的分析解决方案应当尝试将应用程序移到一个隔离的测试环境中,在这个环境中应当可以重现问题并进行分析,而不会影响生产服务器。由于在这些测试环境中重现问题的难度很大,所以相关内存泄漏的成本增加了。
导致这些问题的原因在于传统技术尝试同时执行检测和分析。

No comments: