Java内存泄露模拟及分析解决方法_第1页
Java内存泄露模拟及分析解决方法_第2页
Java内存泄露模拟及分析解决方法_第3页
Java内存泄露模拟及分析解决方法_第4页
Java内存泄露模拟及分析解决方法_第5页
已阅读5页,还剩5页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、文档来源为 :从网络收集整理 .word 版本可编辑 .欢迎下载支持e-mail:derweeJava内存泄露模拟及分析解决方法1.1 实践目标:1、使用JAVA代码实现模拟内存溢出2、分析JDK内存溢出的原因3、总结存在bug的JAVA编码实践4、总结JVM优化的方法1.2 模拟内存溢出:为了方便模拟内存,特意把 JVM的内存参数指定为更小(我的本本内存是8G的)。修改eclipse参数文件 eclipse.ini调用JVM参数:-vmargs-Xms40m (原始是-Xms40m)-Xmx100m (原始是-Xmx384m)演示JAVA小程序实现原理:使用集合类对象装载大量的 Persio

2、n 对象,每次把new出 来的对象加入集合类对象后, 更改对象的属性,再从集合类对象中删除该对象。 会出现该删 除的对象没有被删掉, Persion类对象不断占用内存,导致分配给 JVM的内存被耗光。package ;import java.util.*;* ClassName : OutOfMemory* Description :内存溢出模拟,提出解决方法* author yangdw* date 2012 - 3- 25 下午 6:58:49*/publicclass OutOfMemory publicstaticvoidmain(String args)Collection coll

3、ection =new HashSet();for ( int i=0;in;冋存制i剛由出瀛锻* iautnor yanaiw* :date 2312-3-25 下午&王;49*/public class CQtOfMsjnory public static void main(Spring azgs) Cel lection collection = nei EashSet ();for (int i=0;i9DOO 00000; i+tr/emcr);Jgv5 Appliwtfo-ij C Pr?grarr FileJ打础dkl矶-刃birlj阴20l?3-Z5 T3:20能勃 解黠糕讯

4、曲九测鱗一2酥亜貶4 jExcept ion in thread uh in*1langOut Gf Mem 口 ryErrci 匚;Java heap spaceat亘二stccn A已 tiT 乩 ccllecticr: fneno 二 y CutO zMemo ry .msln CutOf Memory j n且;19)ja fa.UEil.胎dDbj.resiza.4$上世孑口.益yp:462; -ay.util.HashMap.adzZntry(HsshNap.java;755i j av .utLl.Ha hMap. put (HNshXag.割逐 囲勺 -ava .utLl.Hs

5、ahset ,aaci (HmshSet*Fm:2皿1.3 内存溢出原因分析:在JDK中内存划分主要分为堆和栈。堆主要存储对象和数组;栈主要存储 JAVA原生类型变量。一般JDK初始化后栈占用大小变化不大。堆内存是用户使 用的主要部分,大小变化很大,正常的占用图应该是波浪形的。-Xms :启动应用时,JVM堆空间的初始大小值。-Xmx :应用运行中,JVM堆空间的极限值。为了不消耗扩大JVM堆控件分配的开销, 往往此参数和-Xms这个两个值设为相等。当非堆内存大小 +堆内存大小 JVM堆空间的极限值。就会出现 Java heapspace 。解决方法:1、评估应用程序需要内存大小。比如大量大对

6、象存储在集合对象内, 迟迟不处理。应该及时释放稀有资源2、释放方式不合理,以为释放了,其实没有,如上面的演示程序。上面的演示程序中,因为使用了以 hashcode来定位查找的 hashset但对象的name参与计算 hashcode的值被改变了,最后得到的hashcode变了,并没有把该删的对象删除(collectio n.remove(per); /把刚加到集合里的对象删除),集合对象还引用着每一个刚新生成的对象,即使手工调用垃圾回收(System.gc();手工调用垃圾回收器) 也是没有用的。因为手工调用gc方法仅仅是通知JVM而已,至于JVM垃圾回收线程有没有空,能不能成功回收,gc也管

7、不了。集合对象长度(collection.size()说明了内存溢出。1.4 大型工程中内存溢出排查建议1如果在大型工程里排查内存溢出,Jconsole已经不是最优的工具了。因为Jconsole没有提供细到对象级粒度的监控。只能根据应用程序正常状态下耗用内存量,和在异常状态 下耗用内存量比较,可以明确是否存在内存溢出的情况存在。如果已经确定待处理的大 型应用程序存在内存溢出问题,要定位到某个Java对象,某段Java逻辑代码,位于某个Java文件,可以借助JProfiler进行对象级的跟踪,接着定位到相关逻辑代码块。如果这部分的工作给非常熟悉这个应用程序的人排查,应该可以比较快找出存在逻辑问题

8、的代码块。1.5 存在bug的代码实践:其实造成内存溢出,除了物理条件外,往往是代码bug。上面实例是publicinthashCode() 造成的内存溢出,可见这个方法很神奇。在编写代码时往往重写两个方法hashCode 和equals 。hashCode :当在集合类中如 HashSet ,HashMap , Hashtable中存储对象时,要特别注意hashCode的实现,如果得到的哈希码变了,在哈希集合中是无法定位该对象的,岀现删除该对象失败的情况,最终 导致了内存溢岀了。equals :如果要比较对象的内容, 请重写该方法,因为默认的,但String 重写了 equals 方法如:

9、Set companys = new HashSet();companys.add( new StringBuffer();companys.add( new StringBuffer (医;/结果是2Set companys = new HashSet();companys.add( new String( ); companys.add( new String ();/结果是1对于HashSet类是怎么确定一个对象是否已经存在集合类中呢?根据Java源码,HashSet类首先看hashcode方法是否相等,然后看equals方法是否相等。注意:当重写对象的 hashCode和equals

10、,当用到哈希集合时注意不要轻易更改参与哈希码运 算的对象属性,如 person 的id 和name.1.5.1 equals 和 hashcode 重写原则 对 equals() 应该遵循如下要求1) 对称性:如果 x.equals(y) 返回是“ true ”,那么 y.equals(x) 也应该返回 是“ true ”。2) 自反性: x.equals(x) 必须返回是“ true ”。3) 传递性:如果 x.equals(y)返回是“ true ”,而且 y.equals(z)返回是“ true ”,那么 z.equals(x) 也应该返回是“ true ”。4) 任何

11、情况下, x.equals(null) ,永远返回是“ false ”。5) x.equals( 和 x 不同类型的对象 ) 永远返回是“ false ”。 hashCode() 的返回值和 equals() 的关系如下1) 如果 x.equals(y)返回“ true ”,那么 x 和 y 的 hashCode() 必须相等。2) 如果 x.equals(y)返回“ false ”,那么 x 和 y 的 hashCode() 有可能相等,也有可能不等。1.6 基于 JVM 优化开始使用 JDK 默认参数,使用 JDK 自带的 jconsole 连续观察内存使用情况,线程 数,确

12、定基线后,设置合理的优化参数。 根据实际情况定制合适的优化参数,但不要盲 目设置 JVM 的优化参数,可能会触发 JDK 未知 BUG !-Xms :启动应用时, JVM 堆空间的初始大小值。-Xmx :应用运行中, JVM 堆空间的极限值。 为了不消耗扩大 JVM 堆控件分配的开销, 往往此参数和 -Xms 这个两个值设为相等。NewSize :堆中新对象区大小。PermSize 设置非堆内存初始值,默认是物理内存的1/64。MaxPermSize :应用运行中,永久存储区的极限值。如: set JAVA_OPTS=-Xms800m -Xmx800m -XX:PermSize=128M -X

13、X:MaxNewSize=256m -XX:MaxPermSize=256m优化原则:1、在 JVM 中如果 98的时间用于 GC 且可用的 Heap size 不足 2的时候将抛出此异常信 息。2、 Heap Size最大不要超过可用物理内存的80%, 般的要将-Xms和-Xmx选项设置为相 同,而 -Xmn 为 1/4 的 -Xmx 值。3、 JVM初始分配的内存由-Xms指定,默认是物理内存的1/64;VM最大分配的内存由-Xmx 指定,默认是物理内存的 1/4。4、默认空余堆内存小于 40%时, JVM 就会增大堆直到 -Xmx 的最大限制;空余堆内存大于 70%时, JVM 会减少堆

14、直到 -Xms 的最小限制。因此服务器一般设置 -Xms、 -Xmx 相等 以避免在每次 GC 后调整堆的大小。5、内存分配大小 2GB-3GB (般来说 Windows系统下为1.5G-2G,Linux系统下为2G-3G ), 而 64bit 以上的处理器就不会有限制了。1.6.1 JVM 监控工具介绍JCONSOLE这是随着JDK分发的一个图形化 JVM监控工具,可以观察到 java进程的gc, class,内 存等信息。在主界面中有 6 大 tab 页:1. 概述:有关堆内存使用情况,线程,类加载和 CPU 使用情况的总体情况,支 持时间范围查询2. 内存:内存的详细情况,堆和其他内存,支持时间粒度查询3. 线程:峰值 /活动线程、各个线程的明细信息、检测死锁4. 类:监控加载和卸载的类5. vm 摘要:有关 vm 的明细信息6. MBean :当前Java程序的 MBean的操作支持本地 JVM 和远程 JVM 监控。JProfilerJProfiler是一个全功能的Java剖析工具,主要用于检查和跟踪系统(限于 Java

温馨提示

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

评论

0/150

提交评论