性能优化工具-MAT的使用

Python019

性能优化工具-MAT的使用,第1张

最近在写性能优化专题相关文章,依次写了“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源码中造成该泄漏可疑点的地方,很容易去定位问题。

public class Yanghui {

public Yanghui() {

}

//用来在每一次打印前面加空格, 看的整齐

public static String addSpace(int i) {

String str = String.valueOf(i)

int len = str.length()

for (int j = 0j <4 - lenj++) {

str = " " + str

}

return str

}

public static void main(String args[]) {

int i, j, n = 10

int mat[][] = new int[n][]

for (i = 0i <ni++) {

mat[i] = new int[i + 1]

mat[i][0] = 1

mat[i][i] = 1

int matLen = mat[i].length - 2

//只对每行的元素个数超过2个的才进行循环赋值

if(matLen >0)

{

for (j = 0j <matLenj++)

{

mat[i][j + 1] = mat[i - 1][j + 1] + mat[i - 1][j]

}

}

}

for (i = 0i <mat.lengthi++) {

for (j = 0j <mat[i].lengthj++)

//需要其它不同的打印方式, 可以自己调试的加上去.

System.out.print(addSpace(mat[i][j]))

System.out.println()

}

}

}

对于每一个java进程来说都有自己的内存池和使用空间,而这也就意味着会出现内存使用错误等问题,而这时候我们就需要对java内存进行诊断分析,今天云南java培训http://www.kmbdqn.cn/就一起来了就一下,在进行内存诊断上都有哪些软件可以使用。

Java堆:分析诊断数据

堆转储分析

堆转储可以使用如下的工具进行分析:

EclipseMAT(内存分析工具,MemoryAnalyzerTool)是一个社区开发的分析堆转储的工具。它提供了一些很棒的特性,包括:

可疑的泄漏点:它能探测堆转储中可疑的泄露点,报告持续占有大量内存的对象

直方图:列出每个类的对象数量、浅大小(shallow)以及这些对象所持有的堆。直方图中的对象可以很容易地使用正则表达式进行排序和过滤。这样有助于放大并集中我们怀疑存在泄露的对象。它还能够对比两个堆转储的直方图,展示每个类在实例数量方面的差异。这样能够帮助我们查找Java堆中增长快的对象,并进一步探查确定在堆中持有这些对象的根

不可达的对象:MAT有一个非常棒的功能,那就是它允许在它的工作集对象中包含或排除不可达/死对象。如果你不想查看不可达的对象,也就是那些会在下一次GC周期中收集掉的对象,只关心可达的对象,那么这个特性是非常便利的

重复的类:展现由多个类加载器所加载的重复的类

到GC根的路径:能够展示到GC根(JVM本身保持存活的对象)的引用链,这些GC根负责持有堆中的对象

OQL:我们可以使用对象查询语言(ObjectQueryLanguage)来探查堆转储中的对象。它丰富了OQL的基础设施,能够编写复杂的查询,帮助我们深入了解转储的内部。

JavaVisualVM:监控、分析和排查Java语言的一站式工具。它可以作为JDK工具的一部分来使用,也可以从GitHub上下载。它所提供的特性之一就是堆转储分析。它能够为正在监控的应用创建堆转储,也可以加载和解析它们。从堆转储中,它可以展现类的直方图、类的实例,也能查找特定实例的GC根

jhat命令工具(在/bin文件夹中)提供了堆转储分析的功能,它能够在任意的浏览器中展现堆转储中的对象。默认情况下,Web服务器会在7000端口启动。jhat支持范围广泛的预定义查询和对象查询语言,以便于探查堆转储中的对象

Java任务控制(JavaMissionControl)的JOverflow插件:这是一个实验性的插件,能够让Java任务控制执行简单的堆转储分析并报告哪里可能存在内存浪费

Yourkit是一个商业的Javaprofiler,它有一个堆转储分析器,具备其他工具所提供的几乎所有特性。除此之外,YourKit还提供了:

可达性的范围(reachabilityscope):它不仅能够列出可达和不可达的对象,还能按照它们的可达性范围显示它们的分布,也就是,强可达、弱/软可达或不可达

内存探查:YourKit内置了一组全面的查询,而不是使用ad-hoc查询功能,YourKit的查询能够探查内存,查找反模式并为常见的内存问题分析产生原因和提供解决方案。