在java中用弱引用堵住内存泄漏

在java中用弱引用堵住内存泄漏

ID:34456680

大小:85.50 KB

页数:9页

时间:2019-03-06

在java中用弱引用堵住内存泄漏_第1页
在java中用弱引用堵住内存泄漏_第2页
在java中用弱引用堵住内存泄漏_第3页
在java中用弱引用堵住内存泄漏_第4页
在java中用弱引用堵住内存泄漏_第5页
资源描述:

《在java中用弱引用堵住内存泄漏》由会员上传分享,免费在线阅读,更多相关内容在工程资料-天天文库

1、在JAVA中用弱引用堵住内存泄漏本文章由91913网址导航www.91913.cn整理,供更多的IT学习者学习。弱引用能让表达对象生命周期关系变得更加容易,虽然用Java™语言编写的程序在理论上是不会出现“内存泄漏”的,但是有时对象在不再作为程序的逻辑状态的一部分之后仍然不被垃圾收集。本月,负责保障应用程序健康的工程师BrianGoetz探讨了无意识的对象保留的常见原因,并展示了如何用弱引用堵住泄漏。要让垃圾收集(GC)回收程序不再使用的对象,对象的逻辑生命周期(应用程序使用它的时间)和对该对象拥有的引用的实际生命周期必须是相同的

2、。在大多数时候,好的软件工程技术保证这是自动实现的,不用我们对对象生命周期问题花费过多心思。但是偶尔我们会创建一个引用,它在内存中包含对象的时间比我们预期的要长得多,这种情况称为无意识的对象保留(unintentionalobjectretention)。弱引用和弱集合是对堆进行管理的强大工具,使得应用程序可以使用更复杂的可及性方案,而不只是由普通(强)引用所提供的“要么全部要么没有”可及性。下个月,我们将分析与弱引用有关的软引用,将分析在使用弱引用和软引用时,垃圾收集器的行为。全局Map造成的内存泄漏无意识对象保留最常见的原因是

3、使用Map将元数据与临时对象(transientobject)相关联。假定一个对象具有中等生命周期,比分配它的那个方法调用的生命周期长,但是比应用程序的生命周期短,如客户机的套接字连接。需要将一些元数据与这个套接字关联,如生成连接的用户的标识。在创建Socket时是不知道这些信息的,并且不能将数据添加到Socket对象上,因为不能控制Socket类或者它的子类。这时,典型的方法就是在一个全局Map中存储这些信息,如清单1中的SocketManager类所示:清单1.使用一个全局Map将元数据关联到一个对象publicclassSo

4、cketManager{privateMapm=newHashMap();publicvoidsetUser(Sockets,Useru){m.put(s,u);}publicUsergetUser(Sockets){returnm.get(s);}publicvoidremoveUser(Sockets){m.remove(s);}}SocketManagersocketManager;...socketManager.setUser(socket,user);这种方法的问题是

5、元数据的生命周期需要与套接字的生命周期挂钩,但是除非准确地知道什么时候程序不再需要这个套接字,并记住从Map中删除相应的映射,否则,Socket和User对象将会永远留在Map中,远远超过响应了请求和关闭套接字的时间。这会阻止Socket和User对象被垃圾收集,即使应用程序不会再使用它们。这些对象留下来不受控制,很容易造成程序在长时间运行后内存爆满。除了最简单的情况,在几乎所有情况下找出什么时候Socket不再被程序使用是一件很烦人和容易出错的任务,需要人工对内存进行管理。找出内存泄漏程序有内存泄漏的第一个迹象通常是它抛出一个O

6、utOfMemoryError,或者因为频繁的垃圾收集而表现出糟糕的性能。幸运的是,垃圾收集可以提供能够用来诊断内存泄漏的大量信息。如果以-verbose:gc或者-Xloggc选项调用JVM,那么每次GC运行时在控制台上或者日志文件中会打印出一个诊断信息,包括它所花费的时间、当前堆使用情况以及恢复了多少内存。记录GC使用情况并不具有干扰性,因此如果需要分析内存问题或者调优垃圾收集器,在生产环境中默认启用GC日志是值得的。有工具可以利用GC日志输出并以图形方式将它显示出来,JTune就是这样的一种工具(请参阅参考资料)。观察GC之

7、后堆大小的图,可以看到程序内存使用的趋势。对于大多数程序来说,可以将内存使用分为两部分:baseline使用和currentload使用。对于服务器应用程序,baseline使用就是应用程序在没有任何负荷、但是已经准备好接受请求时的内存使用,currentload使用是在处理请求过程中使用的、但是在请求处理完成后会释放的内存。只要负荷大体上是恒定的,应用程序通常会很快达到一个稳定的内存使用水平。如果在应用程序已经完成了其初始化并且负荷没有增加的情况下,内存使用持续增加,那么程序就可能在处理前面的请求时保留了生成的对象。清单2展示了

8、一个有内存泄漏的程序。MapLeaker在线程池中处理任务,并在一个Map中记录每一项任务的状态。不幸的是,在任务完成后它不会删除那一项,因此状态项和任务对象(以及它们的内部状态)会不断地积累。清单2.具有基于Map的内存泄漏的程序publiccl

当前文档最多预览五页,下载文档查看全文

此文档下载收益归作者所有

当前文档最多预览五页,下载文档查看全文
温馨提示:
1. 部分包含数学公式或PPT动画的文件,查看预览时可能会显示错乱或异常,文件下载后无此问题,请放心下载。
2. 本文档由用户上传,版权归属用户,天天文库负责整理代发布。如果您对本文档版权有争议请及时联系客服。
3. 下载前请仔细阅读文档内容,确认文档内容符合您的需求后进行下载,若出现内容与标题不符可向本站投诉处理。
4. 下载文档时可能由于网络波动等原因无法下载或下载错误,付费完成后未能成功下载的用户请联系客服处理。