关于JAVA应用程序中的内存泄漏研究

时间:2022-06-21 03:47:51

关于JAVA应用程序中的内存泄漏研究

摘要 自从java问世以来,人们对该平台的安全及由技术带来的安全问题越来越关注。而JAVA的内存泄漏问题则是影响系统稳定性的关键因素之一。本文在阐述JAVA内存泄漏定义的基础上,介绍几种比较典型的内存泄漏,并提出发现、解决及防范内存泄漏的方法。

关键词 JAVA;内存泄漏

中图分类号TP39 文献标识码A 文章编号 1674-6708(2011)46-0208-01

1 JAVA内存泄漏的定义

JAVA中的内存泄漏是指存在一些被分配的对象,它们有两个特点:其一,这些对象在有向图中可以与存在通路相连,即可达性;其二,程序在后续不会再使用这些对象,即无用性。假如被分配的对象同时满足这两个条件,即可判定其为JAVA中的内存泄漏,GC不会将其进行回收,因此它们占用内存。

2 几种典型的内存泄漏

2.1失效对象未被彻底清除

最常见的是引用废弃聚集,当对象加入一个聚集时就不再被需要,但是未没有被移除,特别是此聚集用St atic声明,并存在于程序的整个生命周期时,该问题尤其突出;此外还有一种由于引用临时对象而产生的错误,临时对象经过使用就会变成垃圾,如果仍保持引用,GC就无法回收这些失效对象,从而产生内存泄漏。要解决这类问题,可以采用以下几种方法:如果引用了失效对象要及时清除;尽可能少用静态集合和临时对象;对象如果不用尽量设置为Null等。

2.2全局集合

几乎所有的大型应用程序都会有不同形式的全局数据库,而在FAVA中全局变量无法在所有类这之外进行定义,其全局变量只可以利用在一个类中对静态、公用的变量进行定义的方法来实现,而静态变量会永驻内存,因此导致内存泄漏的问题在所难免。可以利用清除作业解决该问题,这个作业为周期运行,可以验证数据中的数据,将无用的数据清除。此外还可以通过引用记数的方法来解决,集合的主要对集合中每个元素的引用者数量进行统计,引用者将不再引用元素的通知发送给集合;假如引用者数量为零,集合中的该元素就可以进行移除。

3 内存泄漏的检测及处理与改进措施

3.1内存泄漏的检测

通常系统处于正常运行的情况下,其内存占用量通常是稳定的,而不应出现无限增长的问题;与此对应的,任何一个类的对象使用个数也同样有一个上限,也不能无限增长。按照这种假设可以对系统在运行过程序所使用的内存大小及实例个数进行持续观察:假如内存大小不断增长,或者特定类的实例对象数量随着时间不断增长,那么该系统就有存在内存泄漏的可能。还有一种方法可以判断是否出现内存泄漏:如果应用程序中出现Out Of Memory Error,系统也有发生内存泄漏的可能,当然不能排除应用程序正在使用的内存量确实是这么多,但是多数情况下出现Out Of Memory Error均有可能出现了内存泄漏。此外,还可以对GC的活动进行持续的监控,如果随着时间的增加系统内存使用量也不断上升,那就有发生内存泄漏的可能。

3.2内存泄漏的处理方法

当检测到确实出现了内存泄漏,进行处理时就要利用专业工具,这些工具采用字节码技术及JVMTI等方法由JVM获取内存系统信息。其中JVMTI为标准接口,其前身是JVMPI,其作为外部工具与JVM通信,搜集JVM的信息;而字节码仪器所引用的是预处理技术,该技术利用探针获取工具所需要的字节信息。不过目前多数处理内存泄漏的工具均是基于JVMTI进行的,JVMTI会使系统的内存增加,执行程序的速度变慢。而另外一种工具JRockit Memory Leak Detector是基于BEAJVM运行的,它内嵌于BEAJ Rockit JVM,系统全速运行时也可以使用,而且不会出现其它与此类工具相关联的性能开销,所以不存在上述缺点。应用JRockit Memory Leak Detector处理内存泄漏可以经由以下几个步骤来实现:

首先借助趋势分析找出存在泄漏的对象类,JRockit Memory Leak Detector所提供的趋势分析功能可以描述应用程序中各类使用堆空间的情形,可以通过它了解某一类型实例所占用空间的大小,或者占用了堆的哪一部分,存在实例的数量和堆空间使用的每秒增加速度,其中增长过快的对象就值得怀疑。其次,寻找与泄漏对象相关的其它类,通过对趋势分析表的分析选择一个可疑类型,所有具有指向选中类型的实例的类型均可以在一个图中显示出来,用户就能够回溯到造成引用的根本原因。类的实例能够被显示、内观,指向一个选中实例的所有实例均能够显示于一张实例图,可以通过分配跟踪对某个类的分配情况进行跟踪。最后再向下发掘,找出独立的对象间互相联系的方式。此外,该工具还可以动态的寻找所有内存分配的堆栈路径,同时通过上述3种特性,可以把该工具集成在JVM中,从而对内存泄漏进行安全有效的捕捉与修复。

3.3内存泄漏的改进措施

在实际应用过程中,如果可以结合GC的运行机制,在进行设计与编码时更具针对性,从而有效的减少或者消除内存泄漏。具体的措施如下:第一,尽量少用静态对象变量或者静态集合类,因为被静态集合类引用的对象无法被GC回收,易导致内存泄漏;第二,使用内部类要谨慎,因为内部类中往往隐藏有外部类对象实例的引用,如果未得到释放会造成整个系列对象无法释放;第三,不可采用生命周期长的对象去管理生命周期短的对象;第四,物理连接要及时关闭;第五,释放资源或者清除引用时要调用对象的特定方法;第六,清除本地的系统资源时可以采用Finalize方法。

参考文献

[1]冯涛,宋成明.清剿Java程序中的内存泄漏[J].计算机技术与发展,2008(4).

[2]贾晓霞,吴际,金茂忠,等.Java程序内存泄漏综述[J].计算机应用研究,2009(6).

[3]黄山,杨全胜,杜中军,等.Java内存管理和内存泄漏的研究[J].中国民航飞行学院学报,2009(5).

[4]陈华.探讨JAVA的内存泄漏问题[J].IT技术论坛,2008(33).

上一篇:钻孔灌注桩在桥梁工程中的施工技术探讨 下一篇:试论现代电力电子技术的发展趋势及应用