找出Java程序内存溢出的元凶 - 编程入门网
找出Java程序内存溢出的元凶时间:2011-10-28 cuishen我曾经在刚入行的时候做过一个小的swing程序,用到了java SE,swing,Thread等东东,当初经验少 也没有做过严格的性能测试,布到生产环境用了一段时间后发现那个小程序有时候会抛 java.lang.OutofMemoryError异常,就是java的内存溢出。当时也上网查了不少资料,试过一些办法,代 码也稍微做了些优化,但是有一个问题我始终是找不到解决的方案 - 不知为什么子窗体关闭后java的垃 圾回收机制无法回收其资源,因为这个Java程序可能要经常开关一些子窗体,那么这些子窗体关闭后无法 释放资源就造成了Java程序OutOfMemoryError的潜在的隐患! 最近无意间在网上看到了一个监控java程序内存使用的工具 - JProbe,马上回想起那个有关内存溢出 的难题,于是我就下载了JProbe8.0.0希望从分析内存入手找到我要的答案。软件下载安装后,在安装目 录里详尽的用户指南(懂点软件和英语的人很快就能上手),主要是两个步骤: 1.用JProbe Config工具根据提示生成J2SE或者J2EE程序的控制脚本(一个.jpl文件和一个.bat文件) ,在命令行里进入.bat文件所在的目录,然后执行该批处理让要监控的java程序跑起来 2.运行JProbe Console工具,点击“Attach to Session...”按钮,弹出java程序的内存实时监控图 表“Runtime Summary”,我们主要是看“Data”卡片里的内容(注意:第一次使用该软件可能会遇到一 些小问题:比如发布为jar包的程序如果运行时会去读配置文件,从控制脚本启动的话,可能会发生配置 文件找不到的异常,解决办法是:不要打jar包,直接就用文件夹发布;还有可能因为一些杀毒软件的网 络防火墙导致JProbe无法连接到控制脚本的session,造成监控图表打不开,解决办法是:取消防火墙对 于JProbe访问网络的限制) 实时监控图表“Runtime Summary”如下图所示: 可以设置要监视的包或者类,然后点击“Refresh Runtime Data”按钮刷新这些对象占用内存的情况 ,当你觉得某个类比较可疑的话,你可以在不断的使用程序的过程中监视它的生命周期,看看它是否像预 期的那样在结束了生命周期后占用的内存就被释放。众所周知:java的内存回收是自动进行的,无需程序 员干预,我们称其为垃圾回收,这个垃圾回收可能是不定期的,就是当程序占用内存资源比较少的情况下 可能jvm的垃圾回收频率就比较低;反之,java程序消耗内存资源比较多的情况下,垃圾回收的频率和力 度就比较高,这种垃圾回收的不确定性很可能会影响我们的判断,但我们可以点击JProbe监控界面右上方 的“Request a Garbage Collection”(像一个垃圾桶的图标)按钮来向jvm发出垃圾回收的请求,等几 秒后再去点击“Refresh Runtime Data”,这个时候如果那个预期应该已经销毁的对象的类名还是没有从 监控界面下方的class列中消失或者其对象数量没有减少的话(请多试几次,中间可以夹杂些其他增加程 序内存使用的操作以确保jvm确实执行了垃圾回收),那恭喜你!90%的可能性你已经找到了程序的某个缺 陷 这个查找元凶的过程可能是相当耗时的,是对程序员的耐心的挑战。我熬了一下午一晚上,功夫不负 有心人,基本上把我那个小程序的所有内存溢出的漏洞都找到并补上了。事实告诉我之前那个子窗体关闭 后资源无法释放的根本原因是:子窗体虽然调用了dispose()方法,但是子窗体对象的引用一直都在:或 者是被静态HashMap引用、或者是它的内部子线程类没有释放、或者是它的某个事件监听类没有释放(借 用JProbe的火眼金睛一检验,发现问题真是一大堆啊!),so.我们要彻底释放某个对象占用资源的关键 在于找到并释放所有对它的引用! 找 |
凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢! |