今天给各位分享java内存泄露mat的知识,其中也会对java内存泄露的例子进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!
本文目录一览:
1、MAT内存泄露分析(一)2、如何排查Java内存泄露3、性能优化工具-MAT的使用4、什么原因可导致java内存泄漏?5、java内存泄漏关机行不行6、怎么查看java代码是否内存泄露
MAT内存泄露分析(一)
使用adb shell dumpsys meminfo pkgname或者直接使用AndroidStudio里面的memory usage功能然后就会出现如下信息:
eclipse中有一个ddms工具,可以查看线程信息(Threads),内存使用情况(VM Heap),内存分配跟踪(Allocation Tracker),CUP使用情况(Sysinfo CUP load),内存使用饼状图(Sysinfo Memory usage),这里我们暂时用到VM Heap,选择要查看的app进程,点击左上角的show heap updates,选择VM Heap并点击Cause GC按钮,然后就出现下图:
观察data object的Total Size选项,这个是app的创建的java对象做占用的内存大小,Count是总内存的对象的个数,反复的进出一个activity,看data object的Total Size有没有明显的增加,正常情况下进入一个activity的时候会明显增加,退出一个activity会有明显的回落,总体是维持在一个比较稳定的水平如果反复进出activity,Total Size不断上升,那么可能就存在内存泄漏了,需要具体排查
如何排查Java内存泄露
1.打开/tomcat_home/bin/catalina.bat文件
2.加上:set JAVA_OPTS=%JAVA_OPTS% -server -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=D:\heapdump,这样当内存溢出是就会在对应路径下生成dump文件
运行程序打开jdk bin 文件夹下再带的 jvisualvm.exe
选择tomcat线程,打开实时监控页面可以看到对应的堆栈线程和装在类,内存的实时情况
运行程序打开jdk bin 文件夹下再带的 jconsole.exe,可以概览堆栈线程和装在类,内存的全部运行时间情况
下载安装mat,dump分析软件,安装后,点击file open 导入dump文件
打开后,灰色区域为可能发生内存溢出的区域,下带问题描述
选择Histogram,点击shallow列进行排序,找出实例最多的
右键实例最的选择list objects-with incoming references,可在根据正则表达式输入自己想查的类,搜索,后右键打开 path to gc root-exclude phantom/weak/soft etc. references 就可以查出 调用为回收的相关信息。
性能优化工具-MAT的使用
最近在写性能优化专题相关文章,依次写了“Android电量优化全解析”、“Android性能优化全解析”、“Android渲染优化解析”、“Android计算优化解析”。文章中有提到许多性能优化的工具,但由于文章重点都是如何分析性能相关的论述,对工具的使用介绍大都是简单略过,下面简单介绍下性能优化工具-MAT(Memory Analyzer Tool)使用,介绍的顺序为:
MAT工具全称为Memory Analyzer Tool,一款详细分析Java堆内存的工具,该工具非常强大,为了使用该工具,我们需要hprof文件。但是该文件不能直接被MAT使用,需要进行一步转化,可以使用hprof-conv命令来转化,但是Android Studio可以直接转化,转化方法如下:
1.选择一个hprof文件,点击右键选择Export to standard .hprof选项。
2.填写更改后的文件名和路径。
点击OK按钮后,MAT工具所需的文件就生成了!
下面我们用MAT来打开转换后的doctorq.hprof文件:
1.打开MAT后选择File-Open File选择我们刚才生成的doctorq.hprof文件
2.选择该文件后,MAT会有几秒种的时间解析该文件,有的hprof文件可能过大,会有更长的时间解析,解析后,展现在我们的面前的界面如下:
这是个总览界面,会大体给出一些分析后初步的结论。
该视图会首页总结出当前这个Heap dump占用了多大的内存,其中涉及的类有多少,对象有多少,类加载器,如果有没有回收的对象,会有一个连接,可以直接参看(图中的Unreachable Objects Histogram)。
比如该例子中显示了Heap dump占用了41M的内存,5400个类,96700个对象,6个类加载器, 然后还会有各种分类信息。
会列举出Retained Size值最大的几个值,你可以将鼠标放到饼图中的扇叶上,可以在右侧看出详细信息:
图中灰色区域,并不是我们需要关心的,他是除了大内存对象外的其他对象,我们需要关心的就是图中彩色区域,比如图中2.4M的对象,我们来看看该对象到底是啥
该对象是一个Bitmap对象,你如果想知道该对象到底是什么图片,可以使用图片工具gimp工具浏览该对象。
histogram视图主要是查看某个类的实例个数,比如我们在检查内存泄漏时候,要判断是否频繁创建了对象,就可以来看对象的个数来看。也可以通过排序看出占用内存大的对象:
默认是类名形式展示,你也可以选择不同的显示方式,有以下四种方式:
下面来演示一下:
该视图会以占用总内存的百分比来列举所有实例对象,注意这个地方是对象而不是类了,这个视图是用来发现大内存对象的。这些对象都可以展开查看更详细的信息,可以看到该对象内部包含的对象:
这个视图会展示一些可能的内存泄漏的点,比如上图上图显示有3个内存泄漏可疑点,我们以Problem Suspect 1为例来理解该报告,首先我们来看该可疑点详细信息:
上面信息显示ImageCahe类的一个实例0xa50819f8占用了14.19%的内存,具体值为5147200字节(5147200/1024/1024=4.9M),并存放在LinkedHashMap这个集合中,然后我们点击Details跳转到更详细的页面:
这样我们就能找到在我们的app源码中造成该泄漏可疑点的地方,很容易去定位问题。
什么原因可导致java内存泄漏?
Java内存泄露\x0d\x0a\x0d\x0a一般来说内存泄漏有两种情况。一种情况如在C/C++语言中的,在堆中的分配的内存,在没有将其释放掉的时候,就将所有能访问这块内存的方式都删掉(如指针重新赋值);另一种情况则是在内存对象明明已经不需要的时候,还仍然保留着这块内存和它的访问方式(引用)。第一种情况,在Java中已经由于垃圾回收机制的引入,得到了很好的解决。所以,Java中的内存泄漏,主要指的是第二种情况。\x0d\x0a 可能光说概念太抽象了,大家可以看一下这样的例子:\x0d\x0a\x0d\x0a1 Vector v=new Vector(10);\x0d\x0a2 for (int i=1;i
回答于 2022-12-11
java内存泄漏关机行不行
如果程序执行一段时间后抛出一个`java.lang.OutOfMemoryError,内存泄漏肯定是一个很大的疑点。那么什么时候内存泄漏应该成为一个问题?完美主义程序员会回答这个问题全部需要调查和纠正内存泄漏。然而,在得出这个结论之前,还有几个其他的问题需要考虑,包括程序的生命周期和泄漏的大小。
考虑垃圾收集器在应用程序生命周期中可能永远不会运行的可能性。无法保证JVM何时或是否会调用垃圾收集器——即使程序显式调用System.gc()。通常,垃圾收集器不会自动运行,直到程序需要比当前可用内存更多的内存。此时,JVM将首先尝试通过调用垃圾收集器来获得更多的可用内存。如果这种尝试仍然没有释放足够的资源,那么JVM将从操作系统获得更多的内存,直到它最终达到允许的最大值。
以一个小型的Java应用程序为例,它显示一些简单的用户界面元素用于配置修改,并且存在内存泄漏。很有可能在应用程序关闭之前,垃圾收集器甚至不会被调用,因为JVM可能有足够的内存来创建程序所需的所有对象,并有剩余的内存来备用。因此,在这种情况下,即使一些死对象在程序执行时占用了内存,但对于所有实际用途来说,这真的无关紧要。
如果正在开发的Java代码打算一天24小时在服务器上运行,那么内存泄漏比我们的配置实用程序的情况要严重得多。即使是某些代码中本来应该连续运行的最小漏洞,最终也会导致JVM耗尽所有可用的内存。
最后一个考虑是,Java内存泄漏不应该被视为像其他语言(如C++)中发生的那样危险,因为在其他语言中,内存会丢失,永远不会返回到操作系统。在Java应用程序的情况下,对象都是依附在操作系统给JVM的内存资源上。因此,理论上,一旦Java应用程序及其JVM关闭,所有分配的内存都将返回给操作系统。
常见内存泄露情况
长生命周期的对象持有短生命周期对象的引用
例如将ArrayList设置为静态变量,则容器中的对象在程序结束之前将不能被释放,从而造成内存泄漏
连接未关闭
如数据库连接、网络连接和IO连接等,只有连接被关闭后,垃圾收集器才会回收对应的对象。
内部类持有外部类
Java的非静态内部类的这种创建方式,会隐式地持有外部类的引用,而且默认情况下这个引用是强引用,因此,如果内部类的生命周期长于外部类的生命周期 《一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》无偿开源 威信搜索公众号【编程进阶路】 ,程序很容易就产生内存泄漏
如果内部类的生命周期长于外部类的生命周期,程序很容易就产生内存泄漏(你认为垃圾收集器会回收掉外部类的实例,但由于内部类持有外部类的引用,导致垃圾收集器不能正常工作)
解决方法:你可以在内部类的内部显示持有一个外部类的软引用(或弱引用),并通过构造方法的方式传递进来,在内部类的使用过程中,先判断一下外部类是否被回收;
内存泄漏和内存溢出辨析
内存溢出和内存泄露,在程序运行时,都会表现出OOM异常,但是两者还是有本质不同的:
怎么查看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内存泄露mat的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于java内存泄露的例子、java内存泄露mat的信息别忘了在本站进行查找喔。