怎样处理Java程序中的内存漏洞

  介绍

本篇文章为大家展示了怎样处理Java程序中的内存漏洞,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。

Java程序中也有内存漏洞?当然有。与流行的观念相反,在Java   编程中,内存管理仍然是需要考虑的问题。在本文中,您将了解到什么会导致内存漏洞以及何时应该关注这些漏洞。您还有机会实践一下在您自己的项目中解决漏洞问题。   
Java程序中的内存漏洞是如何显现出来的
大多数程序员都知道,使用像Java   这样的编程语言的一大好处就是,他们不必再担心内存的分配和释放问题。您只须创建对象,当应用程序不再需要这些对象时,Java   会通过一种称为“垃圾收集”的机制将这些对象删除。这种处理意味着Java已经解决了困扰其他编程语言的烦人问题,可怕的内存漏洞。真的是这样的吗?   
在深入讨论之前,我们先回顾一下垃圾收集的工作方式。垃圾收集器的工作是发现应用程序不再需要的对象,并在这些对象不再被访问或引用时将它们删除垃。圾收集器从根节点(在   Java   应用程序的整个生存周期内始终存在的那些类)开始,遍历被引用的所有节点进行清除。在它遍历这些节点的同时,它跟踪哪些对象当前正被引用着。任何类只要不再被引用,它就符合垃圾收集的条件。当删除这些对象以后,就可将它们所占用的内存资源返回给   Java虚拟机(JVM)。
所以的确是这样,Java   代码不要求程序员负责内存的管理和清除,它会自动对无用的对象执行垃圾收集。但是,我们要紧记的一点是仅当一个对象不再被引用时才会被统计为无用。图1   说明了这个概念。
图   1. 无用但仍被引用的对象

上面说明了在Java应用程序执行期间具有不同生存周期的两个类,类A   首先被实例化,并会在很长一段时间或程序的整个生存期内存在。在某个时候,B类被创建,类一个添加对这个新创建的类的一个引用。现在,我们假定类B   是某个用户界面小部件,它由用户显示甚至解除。如果没有清除类A对B的引用,则即便不再需要类B,并且即便在执行下一个垃圾收集周期以后,B类   仍将存在并占用内存空间。
何时应该关注内存漏洞
如果您的程序在执行一段时间以后发出java.lang.OutOfMemoryError   错误,则内存漏洞肯定是一个重大嫌疑。除了这种明显的情况之外,何时还应该关注内存漏洞呢?持完美主义观点的程序员肯定会回答,应该查找并纠正所有内存漏洞。但是,在得出这个结论之前,还有几个方面需要考虑,包括程序的生存期和漏洞的大小。   
完全有这样的可能,垃圾收集器在应用程序的生存期内可能始终不会运行。不能保证JVM何时以及是否会调用垃圾收集器——即便程序显式地调用   system . gc()也是如此。通常,在当前的可用内存能够满足程序的内存需求时,JVM不会自动运行垃圾收集器。当可用内存不能满足需求时,JVM   将首先尝试通过调用垃圾收集来释放出更多的可用内存。如果这种尝试仍然不能释放足够的资源,JVM将从操作系统获取更多的内存,直至达到允许的最大极限。   
例如,考虑一个小型Java   应用程序,它显示一些用于修改配置的简单用户界面元素,并且它有一个内存漏洞。很可能到应用程序关闭时也不会调用垃圾收集器,因为JVM   很可能有足够的内存来创建程序所需的全部对象,而此后可用内存则所剩无几。因此,在这种情况下,即使某些“死”对象在程序执行时占用着内存,它实际上并没有什么用途。   
如果正在开发的Java代码要全24天   小时在服务器上运行,则内存漏洞在此处的影响就比在我们的配置实用程序中的影响要大得多。在要长时间运行的某些代码中,即使最小的漏洞也会导致JVM   耗尽全部可用内存。
在相反的情况下,即便程序的生存期较短,如果存在分配大量临时对象(或者若干吞噬大量内存的对象)的任何Java   代码,而且当不再需要这些对象时也没有取消对它们的引用,则仍然可能达到内存极限。
最后一种情况是内存漏洞无关紧要。我们不应该认为Java   内存漏洞像其他语言(如c++)中的漏洞那样危险,在那些语言中内存将丢失,且永远不会被返回给操作系统,在Java   应用程序中,我们使不需要的对象依附于操作系统为JVM所提供的内存资源,所以从理论上讲,一旦关闭Java应用程序及其   JVM,所分配的全部内存将被返回给操作系统。

怎样处理Java程序中的内存漏洞