「java如何检查内存泄漏」java如何检查内存泄漏信息

博主:adminadmin 2023-01-19 22:54:07 348

今天给各位分享java如何检查内存泄漏的知识,其中也会对java如何检查内存泄漏信息进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!

本文目录一览:

怎么查看java代码是否内存泄露

第一阶段 通过jdk的GC输出进行测试

可以在 JAVA_OPTS增加以下参数打开jdk的GC输出日志:

-verbose:gc -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError

打开输出日志,jdk会在每一次的垃圾回收时打印相关日志

第二阶段 通过jmap命令

jmap命令可以获得运行中的jvm的堆的快照,从而可以离线分析堆,以检查内存泄漏,检查一些严重影响性能的大对象的创建,检查系统中什么对象最多,各种对象所占内存的大小等等

第三阶段 通过Eclipse Memory Analyzer 分析工具来分析

Eclipse Memory Analyzer是一种快速的,功能丰富的Java堆分析工具,以下简称MAT,可以帮助查找内存泄露,并减少内存消耗。 这个工具可以对由堆转储产生的数以亿计的对象进行分析,一旦堆转储被解析,可以在打开他的一瞬间,立即得到保留大小的单一对象,提取记录详细的信息,查看为什么这些对象对象资料没有被释放掉。使用这些功能的报告,可以对这些对象进行跟踪,找到内存泄露嫌疑人,也可以得到系统的性能指数,帮助优化系统。

怎么查看java程序是否有内存泄露

一般来说内存泄漏有两种情况。一种情况,在堆中的分配的内存,在没有将其释放掉的时候,就将所有能访问这块内存的方式都删掉(如指针重新赋值);另一种情况则是在内存对象明明已经不需要的时候,还仍然保留着这块内存和它的访问方式(引用)。第一种情况,在Java中已经由于垃圾回收机制的引入,得到了很好的解决。所以,Java中的内存泄漏,主要指的是第二种情况。

可能光说概念太抽象了,大家可以看一下这样的例子:

1 Vector v=new Vector(10);

2 for (int i=1;i100; i++){

3 Object o=new Object();

4 v.add(o);

5 o=null;

6 }

在这个例子中,代码栈中存在Vector对象的引用v和Object对象的引用o。在For循环中,我们不断的生成新的对象,然后将其添加到Vector对象中,之后将o引用置空。问题是当o引用被置空后,如果发生GC,我们创建的Object对象是否能够被GC回收呢?答案是否定的。因为,GC在跟踪代码栈中的引用时,会发现v引用,而继续往下跟踪,就会发现v引用指向的内存空间中又存在指向Object对象的引用。也就是说尽管o引用已经被置空,但是Object对象仍然存在其他的引用,是可以被访问到的,所以GC无法将其释放掉。如果在此循环之后,Object对象对程序已经没有任何作用,那么我们就认为此Java程序发生了内存泄漏。

尽管对于C/C++中的内存泄露情况来说,Java内存泄露导致的破坏性小,除了少数情况会出现程序崩溃的情况外,大多数情况下程序仍然能正常运行。但是,在移动设备对于内存和CPU都有较严格的限制的情况下,Java的内存溢出会导致程序效率低下、占用大量不需要的内存等问题。这将导致整个机器性能变差,严重的也会引起抛出OutOfMemoryError,导致程序崩溃。

如何排查Java内存泄露

1、首先我把JVM内存调小,便于在最短的时间内发现问题,利用jstat观察JVM内存回收的情况和使用情况,期间发现旧生代内存的申请在一直进行,但是GC基本回收不回来内存,所以很坚信如果JVM没有BUG的情况下,肯定是存在内存泄漏的地方,应该是代码有问题。但是如何在不翻遍整个代码的情况下,定位问题呢?

2、我查阅几个JVM内存导出工具,并利用JMAP把JVM全部导出来,但是发现悲催的温斗士下,这些工具根本打不开一个G左右的导出文件,直接报乱七八糟的错误,可能也是我的PC硬件配置不高吧,无奈之下只好找了一台Linux服务器,在其上装了MAT工具,然后把JVM导出文件放到这台服务器上进行分析,结果迅速定位到了存在问题的代码

JMAP导出JVM命令格式如下:

jmap -dump:live,format=b,file=heap.bin pid

MAT使用比较简单,不再介绍,只要选择打开导出的文件即可对哪些对象、类等对内存的使用情况一目了然,从而帮助把有可能出问题的代码范围尽量缩小,不用像大海捞针一样采用人海战术逐行代码排查。

如何判断内存泄漏

内存泄露是指使用内存完成后没有释放,内存增长并不能分辨增长出来的内存是进程真正要用的,还是进程泄露出来的。而CPU的占用是瞬时的、确定的,不存在某个进程申请了CPU占着不用的情况。在稳定性测试(也叫持久测试或疲劳测试)中,需要观察内存是否有泄露。然而使用内存的进程千千万,整个服务器的内存增长似乎也不能判断某个进程的内存有泄露。因此在稳定性测试过程中往往需要全程关注指定进程的内存消耗,比如运行3天、7天。

查看内存使用情况的命令有ps、sar、svmon、vmstat等等,但本文并不从工具使用的角度来介绍,而是从性能测试中关注指标的角度来介绍。如果采用其他命令查看内存,需注意,相似的名字在不同命令当中的含义是不一样的,一定要搞清楚这个字段的真正含义。

例1:Virtual这个词,有时候在内存里面指Paging Space(换页空间),有时指进程空间里面占用的所有分页(包括物理内存和Paging Space中的分页)。

例2:Nmon中的PgIn/PgOut、topas中的PageIn/PageOut是指对文件系统的换页,而vmstat中的pi/po是对Paging Space的换页,而topas P中进程的PAGE SPACE是指进程的Data Segment。

java怎么检查程序内存溢出

java程序大家都知道,内存溢出是经常见的错误,下面从基本的开始分析!

内存溢出是由于没被引用的对象(垃圾)过多造成JVM没有及时回收,造成的内存溢出。如果出现这种现象可行代码排查:

一)是否App中的类中和引用变量过多使用了Static修饰 如public staitc Student s;在类中的属性中使用 static修饰的最好只用基本类型或字符串。如public static int i = 0; //public static String str;

二)是否App中使用了大量的递归或无限递归(递归中用到了大量的建新的对象)

三)是否App中使用了大量循环或死循环(循环中用到了大量的新建的对象)

四)检查App中是否使用了向数据库查询所有记录的方法。即一次性全部查询的方法,如果数据量超过10万多条了,就可能会造成内存溢出。所以在查询时应采用“分页查询”。

五)检查是否有数组,List,Map中存放的是对象的引用而不是对象,因为这些引用会让对应的对象不能被释放。会大量存储在内存中。

六)检查是否使用了“非字面量字符串进行+”的操作。因为String类的内容是不可变的,每次运行"+"就会产生新的对象,如果过多会造成新String对象过多,从而导致JVM没有及时回收而出现内存溢出。

如String s1 = "My name";

String s2 = "is";

String s3 = "xuwei";

String str = s1 + s2 + s3 +.........;这是会容易造成内存溢出的

但是String str = "My name" + " is " + " xuwei" + " nice " + " to " + " meet you"; //但是这种就不会造成内存溢出。因为这是”字面量字符串“,在运行"+"时就会在编译期间运行好。不会按照JVM来执行的。

在使用String,StringBuffer,StringBuilder时,如果是字面量字符串进行"+"时,应选用String性能更好;如果是String类进行"+"时,在不考虑线程安全时,应选用StringBuilder性能更好。

知道原因了,解决起来就非常简单了。

java如何检查内存泄漏的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于java如何检查内存泄漏信息、java如何检查内存泄漏的信息别忘了在本站进行查找喔。