java内存泄露溢出检查方法和工具

上传人:仙*** 文档编号:89714147 上传时间:2022-05-13 格式:DOC 页数:11 大小:563KB
收藏 版权申诉 举报 下载
java内存泄露溢出检查方法和工具_第1页
第1页 / 共11页
java内存泄露溢出检查方法和工具_第2页
第2页 / 共11页
java内存泄露溢出检查方法和工具_第3页
第3页 / 共11页
资源描述:

《java内存泄露溢出检查方法和工具》由会员分享,可在线阅读,更多相关《java内存泄露溢出检查方法和工具(11页珍藏版)》请在装配图网上搜索。

1、JAVA内存泄露、溢出的检查方法、工具介绍问题发现:在我们运行的一个项目上线运营后发现运行两天左右就会报内存溢出,只有重启 tomcat才能恢复服务,异常信息如下:java .Ian g.OutOfMemoryError: GC overhead limit exceededjava .Ian g.OutOfMemoryError: Java heap space原因分析:在此之前必须先介绍一下关于jvm的内存控制,JVM即java虚拟机,它运行时候占 用一定的内存,其大小是有限定的,如果程序在运行时jvm占用的内存大于某个限度,则会产生内存溢出,也就是“ java.lang.outofmem

2、oryerror”。如果jvm内存的没有限度,并且有无限大的内存,那jvm就永远不会出现内存溢出了。很明显无限的内存是不 现实的,但是一般情况下我们程序运行过程所需要的内存应该是一个基础固定的值,如 果仅是因为我们的项目所需内存超过了jvm设置内存值导致内存溢出,那么我们可以通过增大jvm的参数设置来解决内存溢出的问题。详细处理可参考java jvm 的如下参数设置:-Xms -Xmx -Xmn -Xss-Xms:设置JVM初始内存,此值可以设置与-Xmx相同,以避免每次垃圾回收完成后 JVM重新分配内存。-Xmx:设置JVM最大可用内存。-Xmn:设置年轻代大小,整个堆大小=年轻代大小+年老

3、代大小+持久代大小.持久代 一般固定大小为64m,所以增大年轻代后,将会减小年老代大小.此值对系统性能影响较 大,Sun官方推荐配置为整个堆的3/8.-Xss:设置每个线程的堆栈大小.在相同物理内存下,减小这个值能生成更多的线程 但是操作系统对一个进程内的线程数还是有限制的,不能无限生成。在jvm参数调试过程中,发现分配最大内存数超过1G后,仍然会产生内存溢出的现象,而估计其正常分配使用的内存应该不会超过1G那么由此可以基本断定其存在内存泄露现象,也就是一些原来分配的不再使用的内存不能被java的垃圾回归所回收,导致不断占用原分配的内存而不释放,导致不断申请更多的内存直到超过内存设置而导致内存

4、溢出。内存泄露的基本原理:在C+语言程序中,使用new操作符创建的对象,在使用完毕后应该通过delete操作符显示地释放,否则,这些对象将占用堆空间,永远没有办法得到回收,从而引起 内存空间的泄漏。如下的简单代码就可以引起内存的泄漏:void fun ctio n()In t vec = new in t5;在function。方法执行完毕后,vec数组已经是不可达对象,在 C+语言中,这样 的对象永远也得不到释放,称这种现象为内存泄漏。而Java是通过垃圾收集器(Garbage Collection ,GC)自动管理内存的回收,程序 员不需要通过调用函数来释放内存,但它只能回收无用并且不再被

5、其它对象引用的那些 对象所占用的空间。在下面的代码中,循环申请Object对象,并将所申请的对象放入一个Vector中,如果仅仅释放对象本身,但是因为 Vector仍然引用该对象,所以这个 对象对GC来说是不可回收的。因此,如果对象加入到Vector后,还必须从Vector中删除,最简单的方法就是将 Vector对象设置为null。Vector v = new Vector(10);for (int i = 1; i 100; i+)Object o = new Object();v.add(o); o = n ull;/此时,所有的Object对象都没有被释放,因为变量 v引用这些对象。实际

6、上无用,而还被引用的对象,GC就无能为力了(事实上GC认为它还有用),这 一点是导致内存泄漏最重要的原因。而我们的项目可能是存在着内存泄露问题而导致内存溢出。解决过程:如何查找引起内存泄漏的原因呢?一般有两种思路:第一种,安排有经验的编程人员 对代码进行走查和分析,找出内存泄漏发生的位置 ;第二种,就是利用一些内存检查分 析工具来分析,找出内存泄露的具体位置可以快速解决。软件测试的理论告诉我们,系统中永远存在一些没有暴露出来的问题,而且,系统 的稳定性问题也不仅仅只是内存泄漏的问题,代码走查是提高系统的整体代码质量乃至 解决潜在问题的有效手段。但在此仅总结一下本次问题解决所应用的有关内存检查和

7、分 析命令以及工具的相关介绍。第一阶段 通过jdk的GC输出进行测试可以在JAVA_OPTS曾加以下参数打开jdk的GC输出日志:-verbose:gc -XX:+Pri ntGCDetails -XX:+He apDump On OutOfMemoryError打开输出日志,jdk会在每一次的垃圾回收时打印相关日志,参考格式如下:GC : - vending occupa ncy1, secs vstarting occupancy3 - vending occupancy3, vpause time3 secsGC收集器的名称vstarting occupancy1新生代在GC前占用的内存

8、vending occupancy1 新生代在GC后占用的内存vpause time1新生代局部收集时jvm暂停处理的时间vstarting occupancy3 JVM Heap在 GC前占用的内存vending occupancy3 JVM Heap 在 GC后 占用的内存vpause time3 GC过程中jvm暂停处理的总时间例:GC PSYoungGen:131072K-10667K(152896K) 137699K-17295K(1551040K), 0.0210980 secs Times: user=0.06 sys=0.01, real=0.02 secs注意短时间内关注GC

9、勺内存回收日志是没有什么作用的,重点需要关注的是Full级别的新生代和年老代的内存情况。如下表中,发现年老代内存是不断增长的,基本可以确定是年老代内存泄露,有许 多长时间未使用的分配内存得不到回收。PSYoungGen:6735K-0K(152896K) PSOldGen: 000000K- 6627K(1398144K)6735K-6627K(1551040K)PSPermGen: 17676K-17676K(262144K), 0.1521720 secs Times: user=0.15 sys=0.01, real=0.16 secsPSYoungGen: 4754K-0K(15360

10、0K) PSOldGen: 201914K-86024K(1398144K)206668K-86024K(1551744K)PSPermGen: 33065K-33065K(262144K), 0.5517640 secs Times: user=0.56 sys=0.00, real=0.55 secsPSYoungGen: 5495K-0K(164096K)PSOldGen:166076K-99609K(1398144K)171571K-99609K(1562240K)PSPermGen: 33680K-33680K(262144K), 0.5221250 secs Times: user

11、=0.52 sys=0.00, real=0.52 secsPSYoungGen: 2584K-0K(164736K)PSOldGen:194684K-76213K(1398144K)197268K-76213K(1562880K)PSPermGen: 34027K-33173K(262144K), 0.6575180 secs Times: user=0.66 sys=0.00, real=0.66 secsPSYoungGen: 928K-0K(161728K)_PSOldGen: 144867K- 100205K(1398144K)_145795K-100205K(1559872K)PS

12、PermGen: 34264K-34264K(262144K), 0.5328980 secs Times: user=0.53 sys=0.00, real=0.53 secsPSYoungGen: 1656K-0K(161984K) PSOldGen: 100205K- 100602K(1398144K) 101861K-100602K(1560128K)PSPermGen: 34317K-34317K(262144K), 0.4965370 secs Times: user=0.50 sys=0.00, real=0.50 secs泄露的结果是确定的,但是内存泄露点到底在哪根据日志也无法

13、确切的查看清楚, 通过在测试机器上的测试也很难找到哪块的业务操作才引起内存的增长。结果未能解决内存泄露问题。第二阶段通过jmap命令jmap命令可以获得运行中的jvm的堆的快照,从而可以离线分析堆,以检查内存泄 漏,检查一些严重影响性能的大对象的创建,检查系统中什么对象最多,各种对象所占 内存的大小等等命令格式jmap options pid -dump:live,format=b,file=filename-dump 堆到文件,live指明是活着的对象,file指定文件名,pid 是java进程id通过这个命令可以查看系统内存情况,但受限于所展示的内存通过能够保存到几十兆以上的的文件内容,手

14、工分析查看实在是太过辛苦,所以也未能解决。第三阶段 通过Eclipse Memory Analyzer分析工具来分析Eclipse Memory Analyzer是一种快速的,功能丰富的Java堆分析工具,以下简称MAT可以帮助查找内存泄露,并减少内存消耗。这个工具可以对由堆转储产生的数以亿计的对象进行分析,一旦堆转储被解析,可以在打开他的一瞬间,立即得到保留大小的单 一对象,提取记录详细的信息,查看为什么这些对象对象资料没有被释放掉。使用这些 功能的报告,可以对这些对象进行跟踪,找到内存泄露嫌疑人,也可以得到系统的性能 指数,帮助优化系统。下面就来介绍一下如何使用该工具进行分析。前面我们已经

15、介绍了,可以通过jmap命令获得运行中的jvm的堆快照,那么想利 于该工具进行分析第一步仍然是获得堆转储文件。具体命令如下:jmap -dump:format=b,file=jmap.hprof 32460注意,32460为java进程pid值,另外本分析工具支持的文件扩展名为hprof,所以将输出文件名定为hprof,有了这个文件我们就可以通过本工具来分析他。启动Eclipse Memory Analyzer,是不是和eclipse 开发平台非常类似?其实他还可做为eclipse的插件进行集成,在这就不详细介绍了,有兴趣的可以自己研究一下。选择菜单File-Open HeadDump然后选择

16、我们生成的堆转储文件打开后他提示是否自动生成泄露检测报告,我们选择后,点finish完成通过图中,MAT合出了关于本次检测有两处占用内存较多的疑似泄露,下面是详细说明先从26%勺嫌疑人suspect2看起,报告很直观的给出系统中有 13个关于数据库链接的 引用对象占用了 59.83%的内存资源,我们还可以点击 details查看一下详细情况。可以看到这13个数据库链接引用其实就是数据库链接池的数据库链接对象。而数据库 链接对象本身仅占用100K左右内存,因此不可能达到26M的内存占用量,所以基本可 以断定是数据库链接占用了原查询过程中的一些结果集等对象的引用,造成内存泄露问题。分析数据库链接池

17、对象的相关代码,未发现数据库链接对象对其它对象的引用占用 情况,后来通过一篇文档资料中介绍如下:在MySQL jdbc 5.1.6 里,默认情况下,如果一个 Connection永远不掉用close, 即使你每一个Statement, ResultSet都调用了 close,仍然会有内存泄漏,换句话说,Stateme nt的close没有把自己的资源释放干净,Stateme nt会在对应的Conn ection里 有缓存在我们的项目中采用了数据库链接池的技术,我们的数据库链接应用完成后不是马 上调用close方法关闭掉,而是返回给了数据库链接池管理。所以链接池中的活动connettion对象中

18、实际上持有了 Statement的引用,造成内存泄露。解决此问题方法就是对connetion对象进行声明,不对statement对象做缓存,具 体代码如下:java.sql.C onn ectio n conn = DriverMa nager.getC onn ectio n(strC onnStrin g);/下面这句很重要,具体作用就是让Stateme nt每次close的时候通知 Conn ection把缓存的Stateme nt对象释放掉,这样就释放干净了com.mysql.jdbc.C onnection connM ysql = (com.mysql.jdbc.C onnection)conn;强制转换connMysql.setDontTrackOpenResources(true);/这个接口是 mysql 特有的 public 函数最终泄露的主要问题解决,另外补充一点一些轻量级别的泄露是需要长期的积累等 其占用较大的资源的时候才能体现出来,所以监测与检测需要时间慢慢积累逐步解决。Page 11 of 9

展开阅读全文
温馨提示:
1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
2: 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
3.本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!