欢迎来到天天文库
浏览记录
ID:34553009
大小:26.72 KB
页数:5页
时间:2019-03-07
《java程序里的内存泄漏是如何表现的》由会员上传分享,免费在线阅读,更多相关内容在工程资料-天天文库。
1、www.027hpedu.comJava程序里的内存泄漏是如何表现的 大多数程序员都知道使用类似于Java的编程语言的好处之一就是他们无需再为内存的分配和释放所担心了。你只需要简单地创建对象,当它们不再为程序所需要时Java会自行通过一个被称为垃圾收集的机制将其移除。这个过程意味着Java已经解决了困扰其他编程语言的一个棘手的问题--可怕的内存泄漏。果真是这样的吗? 在进行深入讨论之前,让我们先回顾一下垃圾收集是如何进行实际工作的。垃圾收集器的工作就是找到程序不再需要的对象并在当它们不再被访问或引用时将它们移除掉。垃圾收集器从贯穿整个程序生命周期的类这个根节点开
2、始,扫描所有引用到的节点。在遍历节点时,它跟踪那些被活跃引用着的对象。那些不再被引用的对象就满足了垃圾回收的条件。当这些对象被移除时被它们占用的内存资源会交还给Java虚拟机(JVM)。 因此Java代码的确不需要程序员负责内存管理的清理工作,它自行对不再使用的对象进行垃圾收集。然而,需要记住的是,垃圾收集的关键在于一个对象在不再被引用时才被统计为不再使用。下图对这一概念进行了说明。 上图表示在一个Java程序执行时具有不同的生命周期的两个类。类A首先被实例化,它存在的时间比较长,几乎贯穿整个进程的生命周期。在某个时间点,类B被创建,类A添加了一个对这个新建类的
3、引用。我们假设类B是某个用于显示并返回用户指令的用户界面部件。尽管类B不再被使用,如果类A对类B的引用未被清除,类B将继续存在并占据内存空间,即使下一次垃圾收集被执行。 什么时候需要注意内存泄漏? 如果在你的程序执行一段时间之后遇到java.lang.OutOfMemoryError的话,内存泄漏无疑是最值得怀疑的。除了这种明显的情况之外,什么时候需要考虑内存泄漏?完美主义的程序员会回答说所有的内存泄漏都需要进行审查和更改。然而,在跳到这一结论之前还需要考虑其他几点因素,包括程序的生命周期以及内存泄漏的大小。www.whhpit.comwww.027hpedu.
4、com 考虑一下在一个程序的生命周期里垃圾收集器可能从未执行的情况。无法保证什么时候JVM会调用垃圾收集--即使程序显式调用System.gc()。通常情况下,垃圾收集器不会自动运行,直到程序需要比目前可用内存还要多的内存。此时,JVM会首先尝试调用垃圾收集器以获取更多可用内存。如果这个尝试仍旧不能够释放出足够的资源,JVM将会从操作系统获取更多内存,直到达到所允许内存的最大值。 举个例子来说,一个小型的Java应用程序,用来显示一些简单的配置修改的用户界面元素,出现了内存泄漏。垃圾收集器可能在程序关闭之前都不会被调用到,因为JVM可能总是有足够的内存来创建程序
5、所需要的所有对象。因此,在这种情况下,即便是一些已死对象在程序运行的时候仍旧占据着内存,但这并不影响实际应用。 如果开发中的Java代码将以每天24小时运行在服务器上,这时内存泄漏将会比上面的那个配置工具程序要明显的多了。即便是代码中最小的内存泄漏,在持续运行的情况下最终也将耗尽所有可用内存。 相反的情况下,即使一个程序只是短暂存活,却分配了大量临时对象(或者少量的占用大量内存的对象),在这些对象不再需要时没有取消引用,这样的Java代码也会达到内存限制。 最后一个值得注意的问题是,不必过于担心(Java程序所造成的)内存泄漏。Java内存泄漏不应该被认为是像
6、其他语言中所发生的那样危险,比如C++的内存丢失将永远不会返回给操作系统。Java应用程序中,我们把不再需要的却占据着内存资源的对象都交给JVM.所以在理论上来说,一旦Java程序和它的JVM关闭掉,所有分配的内存都将归还给操作系统。 如何断定程序具有内存泄漏 查看一个运行在WindowsNT平台上的Java程序是否具有内存泄漏,你可以简单地在程序运行的时候去观察任务管理器中的内存设置。然而,在观察一些运行中的Java程序之后,你会发现,它们跟本地应用程序相比使用更多内存。我开发过的一些Java项目会启用10到20MB的系统内存。与这个数字相比,本地的操作系统自
7、带的WindowsExplorer程序使用到5MB. 另外一个关于Java程序的内存使用要注意的是典型的运行在IBMJDK1.1.8JVM上的程序似乎在其运行时不断吞噬了越来越多的系统内存。程序似乎永远不会返回一些内存给操作系统,直到一个非常大的物理内存分配给它。这会不会就是内存泄漏的迹象? 要明白是怎么回事,我们需要熟悉JVM是如何将系统内存使用作自己的堆的。在运行java.exe时,你可以使用一些特定的选项来控制垃圾收集的堆的启动容量和最大容量(分别是-ms和-mx)。Sun的JDK1.1.8默认使用1MB的启动设置和16MB的最大设置。IBMJDK1.
此文档下载收益归作者所有