处理Java程序中的内存漏洞

发表于:2010-11-25 10:25

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:未知    来源:51Testing软件测试网采编

#
java
#
JAVA
#
Java

  最近碰到一个棘手的问题,在已经展开的稳定性测试中。频繁出现Was宕机等问题,于是在征询了研发组意见后。决定对Was发生宕机前后,进行内存快照。最初的方案是在,Was启动后和发生死机时,使用HeapDump来分析具体程序调用的Java对象。但时间的快照文件却非常难以分析发生宕机时候内存堆内具体的变化情况。由于,需要准确定位到java虚拟机中堆栈的使用情况。由此,我们引用了一个新的测试分析工具jProbe对Was启动时,场景运行的开始点、Action1的结束点以及场景运行的结束点进行内存分析。jProbe的核心思想是通过对比多次快照的内存调用情况,分析出前后两次不同的内存启动后占用比率,从而引导研发推断出程序可能发生问题的对象。

  Java程序中也有内存漏洞?当然有。与流行的观念相反,在Java编程中,内存管理仍然是需要考虑的问题。在本文中,您将了解到什么会导致内存漏洞以及何时应该关注这些漏洞。您还有机会实践一下在您自己的项目中解决漏洞问题。

  Java程序中的内存漏洞是如何显现出来的

  大多数程序员都知道,使用像Java这样的编程语言的一大好处就是,他们不必再担心内存的分配和释放问题。您只须创建对象,当应用程序不再需要这些对象时,Java会通过一种称为“垃圾收集”的机制将这些对象删除。这种处理意味着Java已经解决了困扰其他编程语言的烦人问题 -- 可怕的内存漏洞。是这样的吗?

  在深入讨论之前,我们先回顾一下垃圾收集的工作方式。垃圾收集器的工作是发现应用程序不再需要的对象,并在这些对象不再被访问或引用时将它们删除。垃圾收集器从根节点(在Java应用程序的整个生存周期内始终存在的那些类)开始,遍历被引用的所有节点进行清除。在它遍历这些节点的同时,它跟踪哪些对象当前正被引用着。任何类只要不再被引用,它就符合垃圾收集的条件。当删除这些对象以后,就可将它们所占用的内存资源返回给Java虚拟机 (JVM)。

  所以的确是这样,Java代码不要求程序员负责内存的管理和清除,它会自动对无用的对象执行垃圾收集。但是,要紧记的一点是仅当一个对象不再被引用时才会被统计为无用的。图1说明了这个概念。

  上面说明了在Java应用程序执行期间具有不同生存周期的两个类。类A首先被实例化,并会在很长一段时间或程序的整个生存期内存在。在某个时候,类B被创建,类A添加对这个新创建的类的一个引用。现在,我们假定类B是某个用户界面小部件,它由用户显示甚至解除。如果没有清除类A对B的引用,则即便不再需要类B,并且即便在执行下一个垃圾收集周期以后,类B仍将存在并占用内存空间。

  何时应该关注内存漏洞?

  如果您的程序在执行一段时间以后发出java.lang.OutOfMemoryError错误,则内存漏洞肯定是一个重大嫌疑。除了这种明显的情况之外,何时还应该关注内存漏洞呢?持完美主义观点的程序员肯定会回答,应该查找并纠正所有内存漏洞。但是,在得出这个结论之前,还有几个方面需要考虑,包括程序的生存期和漏洞的大小。

  完全有这样的可能,垃圾收集器在应用程序的生存期内可能始终不会运行。不能保证JVM何时以及是否会调用垃圾收集器 -- 即便程序显式地调用System.gc()也是如此。通常,在当前的可用内存能够满足程序的内存需求时,JVM 不会自动运行垃圾收集器。当可用内存不能满足需求时,JVM将首先尝试通过调用垃圾收集来释放出更多的可用内存。如果这种尝试仍然不能释放足够的资源,JVM 将从操作系统获取更多的内存,直至达到允许的最大极限。

31/3123>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号