精华内容
下载资源
问答
  • MAT内存泄漏分析工具

    2017-04-21 23:13:36
    MAT是一款强大的内存泄漏分析工具,MAT不需要安装,下载解压就能用,下载地址 点击打开链接 1.下面模拟一下内存泄漏 private static TextView sTextView; @Override protected void onCreate(Bundle ...

    MAT是一款强大的内存泄漏分析工具,MAT不需要安装,下载解压就能用,下载地址 点击打开链接

    1.下面模拟一下内存泄漏

      private static TextView sTextView;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            sTextView = new TextView(this);
        }


    2. 然后用DDMS导出hprof的后缀文件。

    保存完文件后还不能直接使用,需要使用 hpro-conv 命令进行转换一下,hprof-conv命令是Android SDK提供的,位于Android SDK platform-tools目录下。

    dos下执行命令hprof-conv com.example.test.hprof  test.hprof


    3.得到test.hprof 然后用MAT打开


    MAT提供的功能很多最常见的就是Histogram和dominator_tree 
    dominator_tree是把内存中的对象大小排序了,而且可以分析他们的引用关系,所以就比较常用。

    我们可以根据大小来查一遍,选中一条然后 -->path to gc roots-->exclude weak/refrences 查看相关的引用关系,从而排查确定内存泄漏的位置。




    展开全文
  • 内存泄漏的代价是巨大的,并且通常直接与生产停机时间或部署进度表延迟有关。 不幸的是,适当的测试解决方案的成本也很高,而且客户通常不愿意-或无法-投资必要的资源。 需要明确的是,解决内存泄漏的最佳方法是在...

    内存泄漏的代价是巨大的,并且通常直接与生产停机时间或部署进度表延迟有关。 不幸的是,适当的测试解决方案的成本也很高,而且客户通常不愿意-或无法-投资必要的资源。

    需要明确的是,解决内存泄漏的最佳方法是在测试中检测并解决它们。 理想情况下,应该有一个测试计划,一个与生产环境相同的测试环境,该环境可以驱动代表性的和异常的工作负载,以及具有专门用于系统测试的技能的技术资源。 这是确保尽可能向生产过渡的最佳方法。 但是,设计和提供这种环境以及相关的文化变化并不是本文的重点。

    Java有四种常见的内存使用问题:

    • Java堆内存泄漏
    • 堆碎片
    • 内存资源不足
    • 本机内存泄漏。

    WebSphere Application Server引入了两种补充技术来帮助客户解决Java堆内存泄漏(在一定程度上,这些工具还解决了由内存资源不足引起的问题;本文未解决这两个问题的相似性)。

    通常,当应用程序无意(由于程序逻辑错误)保留对不再需要的对象的引用时,将导致Java堆内存泄漏。 这些无意的对象引用可防止内置的Java垃圾回收机制释放这些对象使用的内存。 这些内存泄漏的常见原因是:

    • 插入而不删除到集合中
    • 无限缓存
    • 未调用的侦听器方法
    • 无限循环
    • 会话对象过多
    • 编写得不好的自定义数据结构。

    由于配置问题或系统容量问题,可能导致由于内存资源不足而导致的内存使用问题。 例如,可以使用-Xmx参数将Java虚拟机允许的最大堆大小配置为一个太低的值,以致无法容纳内存中的用户会话总数。 或者,系统的物理内存可能太少,无法容纳当前的工作负载。 本机内存泄漏是非Java代码中的内存泄漏。 例如,在Type-II JDBC驱动程序中,或者在Java进程地址空间的非堆段中出现碎片。

    这是一篇介绍性文章,专为Java开发人员,系统管理员和问题确定顾问使用在IBM WebSphere Application Server上部署的应用程序而设计。

    检测内存泄漏根本原因的现有技术存在问题

    有许多问题会导致内存泄漏,这对于系统管理员来说尤其麻烦:

    1. 传统的Java内存泄漏根本原因检测技术具有很大的性能负担,可能不适合在生产环境中使用。 这些技术通常包括堆转储分析,附加JVMPI(Java虚拟机分析器接口)或JVMTI(Java虚拟机工具接口)代理,或使用字节码插入来跟踪集合中的插入和删除。

    2. 传统的冗余方法(例如群集)只能在一定程度上提供帮助。 内存泄漏将在整个群集成员中传播。 受影响的应用服务器的响应速度会减慢工作负载管理技术。 这可能导致将请求路由到更健康的服务器,并导致协调的应用程序服务器崩溃。

    典型的分析解决方案应尝试将应用程序移动到隔离的测试环境中,在该环境中可以重新创建问题,并且可以执行分析而不会影响生产服务器。 在这些测试环境中,复制内存的困难使关联的内存泄漏的成本增加了。

    这些问题的原因是传统技术试图同时进行检测和分析。

    WebSphere解决方案

    WebSphere Application Server V6.0.2和更高版本提供了一个分为两个阶段的解决方案,该解决方案将检测问题与分析分开。

    第一步是在生产WebSphere Application Server运行时中运行的轻量级内存泄漏检测机制。 这种轻量级的检测技术使用便宜的,通用的Java堆使用情况统计信息来监视内存使用情况趋势,并提早通知内存泄漏。 这使管理员有时间准备适当的备份解决方案,并以脱机方式分析问题的根本原因,而不会产生与测试环境中的复制相关的昂贵且令人沮丧的问题。

    解决方案的第二阶段是脱机工具:Java内存转储诊断(MDD4J),用于分析生产应用程序服务器外部的堆转储。 这是一个重量级的脱机内存泄漏分析工具,将多个现有的堆转储分析工具合并到一个用户界面中。

    为了缩小检测与分析之间的鸿沟,已为在IBM JDK上运行的WebSphere Application Server提供了自动堆转储生成工具。 在检测到内存泄漏模式后,此工具将生成多个堆转储,这些堆转储已与足够的内存泄漏进行了协调,以便于使用MDD4J进行比较分析。 另外,如果检测到OutOfMemoryError,则将IBM JDK配置为自动生成堆转储。 管理员应设置负载平衡,或在使用率较低时生成堆转储,以避免短期内性能下降。

    内存泄漏检测

    轻量级内存泄漏检测是通过监视空闲内存的下降趋势来实现的。

    泄漏可能非常快,也可能非常缓慢,因此可以分析短间隔和长间隔的内存使用趋势。 另外,分析了垃圾回收周期后内存使用率的下降趋势,以检测垃圾回收周期后平均可用内存低于某些阈值的情况。 这种情况要么是内存泄漏的迹象,要么是在资源太少的应用程序服务器上运行应用程序。 对于所有平台,此轻量级内存泄漏检测工具可从版本6.0开始在所有版本的WebSphere Application Server上使用。

    另外,专门针对iSeries®平台,iSeries上的WebSphere Application Server包括其他功能,用于检测Java堆大小是否将扩展到DASD上,并发出警报通知管理员即将发生这种情况,以及是否存在这种情况。或者是:

    • 有效内存池大小太小
    • 资源太少
    • 内存泄漏。

    zSeries®支持在6.0.2版中仅包含单个服务方拓扑,但在6.1版中进行了扩展以包括多个服务方拓扑。 单服务方拓扑将V6.0.2中的内存泄漏检测范围限制为问题确定或测试环境。

    图1显示了由内存泄漏检测功能生成的示例通知。 该通知是通过JMX发送的,显示在管理控制台中,并记录在服务器日志中。

    图1.示例内存泄漏通知
    内存泄漏通知示例

    自动堆转储生成工具(仅在IBM JDK上可用)在明显的内存泄漏迹象之后但在应用服务器由于OutOfMemoryError崩溃而生成堆转储。 足够的内存泄漏后,此功能会生成第二个堆转储。 这两个堆转储有助于使用MDD4J进行比较分析。

    自动堆转储生成可以默认启用,也可以在适当的时候使用MBean操作启动。

    WebSphere扩展部署

    尽管可以使用轻量级的内存泄漏检测,并且可以在WebSphere Application Server和WebSphere Application Server Network Deployment中立即使用,但它还是可以完全配置的,并且可以与高级自主管理器或定制JMX客户端进行交互。 WebSphere Extended Deployment是这种关系的一个示例。

    WebSphere Extended Deployment提供了许多配置内存泄漏检测的策略。 一种策略可能是通过对多个堆转储(使用工作负载管理来维护应用程序的性能)进行分析来对内存泄漏通知做出React。 另一个策略可能只是监视应用程序服务器的内存级别何时至关重要,以便在损坏之前重新启动应用程序服务器。

    内存泄漏分析

    一旦检测到内存泄漏并生成了堆转储,就可以将其转移到生产服务器之外,并进入问题确定机器进行分析。

    Java内存转储诊断(MDD4J)是一种脱机堆转储分析工具,可帮助确定内存泄漏的根本原因。 分析机制识别出怀疑的泄漏数据结构类和包。 通过此标识,系统管理员可以将内存泄漏的根本原因缩小到几个组件应用程序。

    WebSphere Application Server提供了用于托管第三方J2EE应用程序的容器。 随着Java堆栈的发展,随着时间的流逝,越来越多的抽象和组件化层被添加到基本Java应用程序和WebSphere Application Server堆栈中。 当发生内存泄漏时,这给确定问题提出了巨大的挑战。 对于遇到内存泄漏的系统管理员来说,托管许多第三方应用程序的WebSphere Application Server就像一个黑匣子。 在这种情况下,第一步是将内存泄漏的根本原因缩小到一个或几个组件。 根本原因通常在于一个错误的组件应用程序。 借助Java内存转储诊断工具的分析结果,系统管理员现在可以更快地识别出故障组件,而无需IBM的任何支持。

    一旦确定了故障组件,系统管理员就可以联系开发人员,他们可以在较小的环境中复制该问题,并在日志记录中使用调试器或特定的跟踪语句来识别故障的源代码方法,并进行必要的更改应用程序代码或配置来解决内存泄漏问题。 有时,了解故障组件或泄漏对象足以使我们确定一些常见的配置问题。 例如,找到许多HTTP会话对象将导致我们查看HTTP会话超时配置。

    该工具提供两种主要类型的分析功能:

    • 单个转储分析最常与内存转储一起使用,内存转储是由Java技术版的IBM Developer Kit(具有OutOfMemoryExceptions异常)自动触发的。 这种类型的分析使用启发式过程来识别具有包含大量子对象的容器对象的可疑数据结构。 这种启发式方法对于检测泄漏的Java集合对象非常有效,这些对象在内部使用数组存储所包含的对象。 已经发现,这种启发式方法在IBM支持部门处理的大量内存泄漏案例中是有效的。

    • 比较分析用于比较在内存泄漏应用程序的单次运行(即,空闲Java堆内存正在删除)期间执行的两个内存转储(主转储和基准转储)。 比较分析非常适合与轻量级内存泄漏检测结合使用。 为了进行比较分析,主转储是指在内存泄漏显着发展之后(消耗大量的最大已配置堆大小)进行的转储。 基线转储指的是由于内存泄漏尚未显着消耗堆的早期进行的堆转储。 转储之间的堆消耗越大,分析结果越好。

      比较分析技术可以识别出一组大型数据结构,这些结构在组成数据类型的实例数量上显着增长。 在每个转储中将数据结构分组在一起,然后在主要转储和基准转储中进行匹配和比较,以识别可疑的数据结构正在经历大量增长。 该技术与当今市场上许多分析工具中可用的基本堆转储差异技术不同,因为该技术以较高的粒度级别识别可疑泄漏数据结构,而不是识别可疑泄漏数据类型(例如,字符串的粒度要低得多)。 例如,MDD4J会告诉您某个特定的容器(例如特定的EJB对象)正在泄漏大量的字符串,而不是简单地告诉您从某个未知源泄漏了大量的字符串。 识别可疑数据结构有助于更好地了解内存泄漏的根本原因。 在图3的树视图中描述了一个示例数据结构,在其中可以看到不仅字符串对象正在泄漏,而且还从类中的HashSet以MyClass的名称引用了它们。

    分析结果显示在具有以下功能的基于Web的交互式用户界面中:

    • 列出分析结果,堆内容,大小和增长的摘要。

    • 列出可疑的数据结构,数据类型和程序包,这些数据结构有助于进行比较分析的堆使用量的增长,并有助于进行单个转储分析的堆的大容量。

    • 所有权上下文视图显示了主要足迹贡献者汇总集合中占足迹的主要贡献者与重要构成数据类型之间的所有权关系。

    • 交互式树视图中的浏览功能显示堆转储的相关部分,显示堆中所有可疑容器对象的所有传入(仅在树中显示一个引用,其余分别显示)和传出引用以及容器的子对象对象,根据到达范围排序。

    • 从可疑列表到所有权上下文,以及从内容视图到浏览视图的导航功能。

    • 具有过滤器和排序列的内存转储中所有对象和数据类型的列表视图。

    MDD4J工具结合了许多现有工具的最佳功能。 比较分析技术是基于Leakbot研究项目(参见相关主题 )。 单转储分析功能使用它也可以在HeapAnalyzer工具下载从alphaWorks(参见发现分析技术相关主题 )。 该表格的观点是基于从一个命令行工具的功能,HeapRoots(参见相关主题 )。

    使用WebSphere Application Server V6.1,用于Java的内存转储诊断(版本1.0)工具与IBM Support Assistant工具(版本3.0)打包在一起,IBM Support Assistant工具(系统管理员的独立工具)也可以从以下位置单独安装(请参阅参考资料 )。可以将堆转储转移到脱机分析的任何机器上的WebSphere Application Server。 (请参阅相关主题 ,了解如何从IBM Support Assistant的3.0版推出MDD4J 1.0版的信息。)

    下载IBM Support Assistant之后,可以使用Updater机制分别添加Java的Memory Dump Diagnostic:在IBM Support Assistant中,在Updater视图中选择New Products and Tools => Common Component and Tools (还请确保WebSphere还安装了Application Server V6.0或V5.0产品插件)。

    此新版本的MDD4J(版本1.0)具有许多与可伸缩性相关的改进,并且比以前的版本(版本0.97a)支持64位堆转储。 (可以将MDD4J的先前版本下载为developerWorks的技术预览;请参阅参考资料 。)

    以下示例显示了一个简单的内存泄漏Java应用程序的内存泄漏分析结果。 此示例应用程序将字符串对象泄漏到静态HashMap中。 轻量级泄漏检测能够在早期识别泄漏的存在并自动生成适当的堆转储。 然后使用Memory Dump Diagnostic for Java Version 1.0中的比较分析对这些转储进行脱机分析。 图2,图3和图4显示了显示可疑内存泄漏的分析结果。

    图2. Memory Dump Diagnostic for Java分析结果中的内存泄漏可疑对象
    Memory Dump Diagnostic for Java分析结果中的内存泄漏可疑对象
    图3.在Memory Dump Diagnostic for Java中浏览可疑的数据结构
    在Memory Dump Diagnostic for Java中浏览可疑的数据结构
    图4.用于Java分析的Memory Dump Diagnostic的占地面积分析
    用于Java分析的Memory Dump Diagnostic的占地面积分析

    结论

    借助WebSphere Application Server V6.1,系统管理员可以在生产环境中及早接收到有关内存泄漏的通知,而无需使用字节码插入或任何附加的代理。 轻量级内存泄漏检测旨在将对性能的影响降到最低,并提供在适当的时间自动生成堆转储的功能,以确保准确的分析结果。

    可以使用Java Memory Dump Diagnostic(MDD4J)离线分析手动生成的堆转储,或借助内存泄漏检测进行堆转储。 该工具可以帮助系统管理员将问题分配给适当的组件,以便开发人员可以在其计算机上轻松复制分析结果。 MDD4J为开发人员和问题确定顾问提供了一种工具,用于识别泄漏的候选对象,浏览堆和所有权链,以确定其代码中泄漏的数据结构。

    这项技术极大地有助于诊断Java堆内存泄漏检测和分析,并且可以与良好的系统测试过程或生产系统一起使用。

    致谢

    作者要感谢:Daniel Julin和Stan Cox审阅了这篇论文; LeakBot项目的首席研究员Nick Mitchell的领导能力和创新能力; Mark T Schleusner在开发MDD4J方面的协助与合作。


    翻译自: https://www.ibm.com/developerworks/websphere/library/techarticles/0606_poddar/0606_poddar.html

    展开全文
  • MAT内存泄漏分析方法

    2019-12-01 23:07:42
    1. MAT下载 https://www.eclipse.org/mat/downloads.php 2. Profiler 获取hprof文件 连上手机,View->Tool Windows -> Profiler 选择process, dump java heap 两次(一次刚开始,一次运行了一段时间) ...

    1. MAT下载

    https://www.eclipse.org/mat/downloads.php

     

    2. Profiler 获取hprof文件

    连上手机,View->Tool Windows -> Profiler

    选择process, dump java heap 两次(一次刚开始,一次运行了一段时间)

    右键 export 存成hprof文件

     

    3. hprov-conv

    在Sdk\platform-tools下运行,hprov-conv 原始.hprof 输出.hprov

     

    4. 运行MemoryAnalyzer

    打开两个hprof文件

    查看Leak Suspects, list objects

    Histogram -> list objects ->with incoming refs 展开后,较浅的被较深的一层引用

    Histogram -> list objects ->merge shortest path to GC roots ->exclue all phantom/weak 

    用这个方法可以快速找到某个对象的 GC Root,一个存在 GC Root的对象是不会被 GC回收掉的

    Dorminator Tree ->Group by class loader

     

     

     

     

     

     

    展开全文
  • Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 ...目录内存泄漏检测实践翻译:使用 Memory Profiler 查看 ...
    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱
    MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina.com

    目录

    内存泄漏检测实践

    1、给项目中集成LeakCanary进行内存泄漏检测,发现有内存泄漏后该工具会进行提示。

    2、有内存泄露后我们使用AS的profiler工具进行分析并获取到.hprof文件:

    • 打开 profiler 工具,点击进入 MEMORY 区域
    • 为了模拟泄漏场景,我们对有内存泄漏的页面进行反复操作,然后点击图中的垃圾桶进行强制gc,再点击垃圾桶旁边的按钮获取堆栈信息
    • 当堆栈信息获取完成后,会在下面弹出一个列表框,我们将排序方式选为Arrange by package,这样好定位我们自己的代码。找到我们的代码后我们真的发现,应该已经被回收了的 Activity 还占用这内存,为什么它没有被销毁,还有那些对象引用着它呢?这时我们就需要点击保存按钮,导出.hprof文件进行具体分析了

    3、导出以后我们会得到一个.hprof文件,但是这个不是 mat 工具用到的标准文件,我们需要使用 sdk 自带的platform-tools/hprof-conv.exe工具进行转换,命令:hprof-conv -z 1.hprof 1_mat.hprof

    4、下来我们就需要使用 mat 进行分析了

    • 打开以后我们点击 Histogram
    • 进入 Histogram 页面,选择Group By package以定位到我们自己的包,然后在搜索框输入我们想要找的类,然后右键选择 merge shortest paths to Gc roots -> exclude all phantom/weak/soft etc.references选项
    • 然后就得到了这个类的引用树,从树中我们分析出我们的 Activity 是被谁引用了。

    可以看到我们的 Activity 是被一个叫 imageView 的对象引用导致无法被释放的,实际上是因为我们的这个 imageView 是静态导致的:

    static ImageView imageView; //静态View导致Activity内存泄漏

    翻译:使用 Memory Profiler 查看 Java 堆和内存分配

    官方文档原文地址

    Memory Profiler 是 Android Profiler 中的一个组件,可帮助您识别导致应用卡顿、冻结甚至崩溃的内存泄漏和流失[memory leaks and memory churn]。它显示一个应用内存使用量的实时图表[It shows a realtime graph of your app's memory use],让您可以捕获堆转储[capture a heap dump]、强制执行垃圾回收[force garbage collections]以及跟踪内存分配[track memory allocations]。

    要打开 Memory Profiler,请按以下步骤操作:

    1. 点击 View > Tool Windows > Android Profiler(也可以点击工具栏中的 Android Profiler )。
    2. 从 Android Profiler 工具栏中选择您想要分析的设备和应用进程
    3. 点击 MEMORY 时间线中的任意位置可打开 Memory Profiler。

    或者,您可以在命令行中使用 dumpsys 检查您的应用内存,同时 查看 logcat 中的 GC Event

    为什么应分析您的应用内存

    Android 提供一个 托管内存环境(managed memory environment) —当它确定您的应用不再使用某些对象时,垃圾回收器会将未使用的内存释放回堆中。 虽然 Android 查找未使用内存的方式在不断改进,但对于所有 Android 版本,系统都必须在某个时间点短暂地暂停您的代码。 大多数情况下,这些暂停难以察觉。 不过,如果您的应用分配内存的速度比系统回收内存的速度快,则当收集器释放足够的内存以满足您的分配需要时,您的应用可能会延迟。 此延迟可能会导致您的应用跳帧[skip frames],并使系统明显变慢。

    尽管您的应用不会表现出变慢,但如果存在内存泄漏,则即使应用在后台运行也会保留该内存。 此行为会强制执行不必要的垃圾回收 Event,因而拖慢系统的内存性能。 最后,系统被迫终止您的应用进程以回收内存。 然后,当用户返回您的应用时,它必须完全重启。

    为帮助防止这些问题,您应使用 Memory Profiler 执行以下操作:

    • 在时间线[timeline]中查找可能会导致性能问题的不理想的内存分配模式[undesirable memory allocation patterns]。
    • 转储 Java 堆以查看在任何给定时间哪些对象耗尽了使用内存。 长时间进行多个堆转储可帮助识别内存泄漏。
    • 记录正常用户交互和极端用户交互期间的内存分配以准确识别您的代码在何处短时间分配了过多对象,或分配了泄漏的对象[allocating objects that become leaked]。

    如需了解可减少应用内存使用的编程做法,请阅读 管理您的应用内存

    Memory Profiler 概览

    当您首次打开 Memory Profiler 时,您将看到一条表示应用内存使用量的详细时间线,并可访问用于强制执行垃圾回收、捕捉堆转储和记录内存分配的各种工具。

    图 1. Memory Profiler

    如图 1 所示,Memory Profiler 的默认视图包括以下各项:

    1. 用于强制执行垃圾回收 Event 的按钮。
    2. 用于捕获堆转储的按钮
    3. 用于记录内存分配情况的按钮。 此按钮仅在连接至运行 Android 7.1 或更低版本的设备时才会显示。
    4. 用于放大/缩小时间线的按钮。
    5. 用于跳转至实时内存数据的按钮。
    6. Event 时间线,其显示 Activity 状态、用户输入 Event 和屏幕旋转 Event。
    7. 内存使用量时间线,其包含以下内容:
      • 一个显示每个内存类别使用多少内存的堆叠图表[stacked graph],如左侧的 y 轴以及顶部的彩色键所示。
      • 虚线表示分配的对象数,如右侧的 y 轴所示。
      • 用于表示每个垃圾回收 Event 的图标。

    不过,如果您使用的是运行 Android 7.1 或更低版本的设备,则默认情况下,并不是所有分析数据均可见。 如果您看到一条消息,其显示“Advanced profiling is unavailable for the selected process”,则需要 启用高级分析 以查看下列内容:

    • Event 时间线
    • 分配的对象数
    • 垃圾回收 Event

    在 Android 8.0 及更高版本上,始终为可调试应用启用高级分析。

    如何计算内存

    您在 Memory Profiler(图 2)顶部看到的数字取决于您的应用根据 Android 系统机制所提交的所有私有内存页面数[private memory pages]。 此计数不包含与系统或其他应用共享的页面。


    图 2. Memory Profiler 顶部的内存计数图例

    内存计数中的类别如下所示:

    • Java:从 Java 或 Kotlin 代码分配的对象内存。
    • Native:从 C 或 C++ 代码分配的对象内存。 即使您的应用中不使用 C++,您也可能会看到此处使用的一些原生内存,因为 Android 框架使用原生内存代表您处理各种任务[handle various tasks on your behalf],如处理图像资源和其他图形时,即使您编写的代码采用 Java 或 Kotlin 语言。
    • Graphics:图形缓冲区队列向屏幕显示像素(包括 GL 表面、GL 纹理等等)所使用的内存。 (请注意,这是与 CPU 共享的内存,不是 GPU 专用内存。)
    • Stack: 您的应用中的原生堆栈和 Java 堆栈使用的内存。 这通常与您的应用运行多少线程有关。
    • Code:您的应用用于处理代码和资源(如 dex 字节码、已优化或已编译的 dex 码、.so 库和字体)的内存。
    • Other:您的应用使用的系统不确定如何分类的内存。
    • Allocated:您的应用分配的 Java/Kotlin 对象数。 它没有计入 C 或 C++ 中分配的对象。

      当连接至运行 Android 7.1 及更低版本的设备时,此分配仅在 Memory Profiler 连接至您运行的应用时才开始计数。 因此,您开始分析之前分配的任何对象都不会被计入。 不过,Android 8.0 附带一个设备内置分析工具,该工具可记录所有分配,因此,在 Android 8.0 及更高版本上,此数字始终表示您的应用中待处理的 Java 对象总数。

    与以前的 Android Monitor 工具中的内存计数相比,新的 Memory Profiler 以不同的方式记录您的内存,因此,您的内存使用量现在看上去可能会更高些。 Memory Profiler 监控的类别更多,这会增加总的内存使用量,但如果您仅关心 Java 堆内存,则“Java”项的数字应与以前工具中的数值相似。

    然而,Java 数字可能与您在 Android Monitor 中看到的数字并非完全相同,这是因为应用的 Java 堆是从 Zygote 启动的,而新数字则计入了为它分配的所有物理内存页面。 因此,它可以准确反映您的应用实际使用了多少物理内存。

    注:目前,Memory Profiler 还会显示应用中的一些误报的原生内存使用量,而这些内存实际上是分析工具使用的。 对于大约 100000 个对象,最多会使报告的内存使用量增加 10MB。 在这些工具的未来版本中,这些数字将从您的数据中过滤掉。

    查看内存分配

    内存分配显示内存中每个对象是_如何_分配的。 具体而言,Memory Profiler 可为您显示有关对象分配的以下信息:

    • 分配哪些类型的对象以及它们使用多少空间。
    • 每个分配的堆叠追踪[stack trace],包括在哪个线程中。
    • 对象在何时_被取消分配_(仅当使用运行 Android 8.0 或更高版本的设备时)。

    如果您的设备运行 Android 8.0 或更高版本,您可以随时按照下述方法查看您的对象分配: 只需点击并按住时间线,并拖动选择您想要查看分配的区域(如视频 1 中所示)。 不需要开始记录会话,因为 Android 8.0 及更高版本附带设备内置分析工具,可持续跟踪您的应用分配。

    https://storage.googleapis.com/androiddevelopers/videos/studio/memory-profiler-allocations-jvmti.mp4
    视频 1. 对于Android 8.0 及更高版本,选择一个现有时间线区域以查看对象分配

    如果您的设备运行 Android 7.1 或更低版本,则在 Memory Profiler 工具栏中点击 Record memory allocations 。 记录时,Android Monitor 将跟踪您的应用中进行的所有分配。 操作完成后,点击 Stop recording (同一个按钮;请参阅视频 2)以查看分配。

    https://storage.googleapis.com/androiddevelopers/videos/studio/memory-profiler-allocations-record.mp4
    视频 2. 对于 Android 7.1 及更低版本,您必须显式记录内存分配

    在选择一个时间线区域后(或当您使用运行 Android 7.1 或更低版本的设备完成记录会话时),已分配对象的列表将显示在时间线下方,按类名称[class name]进行分组,并按其堆计数[heap count]排序。

    注:在 Android 7.1 及更低版本上,您最多可以记录 65535 个分配。 如果您的记录会话超出此限值,则记录中仅保存最新的 65535 个分配。 (在 Android 8.0 及更高版本中,则没有实际的限制。)

    要检查分配记录,请按以下步骤操作:

    1. 浏览列表以查找堆计数异常大且可能存在泄漏的对象。 为帮助查找已知类,点击 Class Name 列标题以按字母顺序排序。 然后点击一个类名称。 此时在右侧将出现 Instance View 窗格,显示该类的每个实例,如图 3 中所示。
    2. Instance View 窗格中,点击一个实例。 此时下方将出现 Call Stack 标签,显示该实例被分配到何处以及哪个线程中。
    3. Call Stack 标签中,点击任意行以在编辑器中跳转到该代码。

    图 3. 有关每个已分配对象的详情显示在右侧的 Instance View 中。

    默认情况下,左侧的分配列表按类名称排列。 在列表顶部,您可以使用右侧的下拉列表在以下排列方式之间进行切换:

    • Arrange by class:基于类名称对所有分配进行分组。
    • Arrange by package:基于软件包名称对所有分配进行分组。
    • Arrange by callstack:将所有分配分组到其对应的调用堆栈[Groups all allocations into their corresponding call stack]。

    在分析时提高应用程序性能

    为了在分析时提高应用程序性能,内存分析器默认情况下会定期对内存分配进行采样[samples ]。 在运行API级别26或更高级别的设备上进行测试时,可以使用“Allocation Tracking”下拉列表更改此行为。

    可用选项如下:

    • Full:捕获内存中的所有对象分配。 这是Android Studio 3.2及更早版本中的默认行为。 如果您有一个分配了大量对象的应用程序,您可能会在分析时观察到应用程序的可见速度下降[observe visible slowdowns]。
    • Sampled:定期在内存中采样对象分配。 这是默认选项,在分析时对应用程序性能的影响较小。 在很短的时间内分配大量对象的应用程序仍然可能会出现明显的减速。
    • Off:停止跟踪应用的内存分配。

    注意:默认情况下,Android Studio会在执行CPU录制时停止跟踪实时分配,并在CPU录制完成后重新打开。 您可以在CPU录制配置对话框中更改此行为。

    查看全局JNI引用

    Java Native Interface(JNI)是一个允许Java代码和 native code 相互调用的框架。

    JNI引用由 native code 手动管理,因此 native code 使用的Java对象可能会保持活动太长时间。如果在没有先明确删除[first being explicitly deleted]的情况下丢弃JNI引用,Java堆上的某些对象可能无法访问。此外,可能耗尽[exhaust]全局JNI引用限制。

    要解决此类问题,请使用Memory Profiler中的 JNI heap 视图浏览所有全局JNI引用,并按Java类型和本机调用堆栈对其进行过滤。通过此信息,您可以找到创建和删除全局JNI引用的时间和位置。

    在您的应用程序运行时,选择要检查的时间轴的一部分,然后从 class list 上方的下拉菜单中选择JNI堆。然后,您可以像往常一样检查堆中的对象,然后双击 Allocation Call Stack 选项卡中的对象,以查看在代码中分配和释放JNI引用的位置,如图4所示。

    要检查应用程序的JNI代码的内存分配,您必须将应用程序部署到运行Android 8.0或更高版本的设备。

    有关JNI的更多信息,请参阅 JNI tips

    捕获堆转储【重要】

    堆转储显示在您捕获堆转储时您的应用中哪些对象正在使用内存。 特别是在长时间的用户会话后,堆转储会显示您认为不应再位于内存中却仍在内存中的对象,从而帮助识别内存泄漏。 在捕获堆转储后,您可以查看以下信息:

    • 您的应用已分配哪些类型的对象,以及每个类型分配多少。
    • 每个对象正在使用多少内存。
    • 在代码中的何处仍在引用每个对象。
    • 对象所分配到的调用堆栈。(目前,如果您在记录分配时捕获堆转储,则只有在 Android 7.1 及更低版本中,堆转储才能使用调用堆栈。)

    图 4. 查看堆转储

    要捕获堆转储,在 Memory Profiler 工具栏中点击 Dump Java heap

    在转储堆期间,Java 内存量可能会暂时增加。 这很正常,因为堆转储与您的应用发生在同一进程中,并需要一些内存来收集数据。

    堆转储显示在内存时间线下,显示堆中的所有类类型,如图 5 所示。

    注:如果您需要更精确地了解转储的创建时间,可以通过调用 [dumpHprofData()](https://developer.android.google.cn/reference/android/os/Debug.html#dumpHprofData(java.lang.String) 在应用代码的关键点创建堆转储。

    在类列表中,您可以查看以下信息:

    • Allocations: 堆中分配数
    • Native Size: 此对象类型使用的native内存总量。 此列仅适用于Android 7.0及更高版本。您将在这里看到一些用Java分配内存的对象,因为Android使用native内存来处理某些框架类,例如Bitmap。
    • Shallow Size: 此对象类型使用的Java内存总量
    • Retained Size: 因此类的所有实例而保留的内存总大小

    您可以使用已分配对象列表上方的两个菜单来选择要检查的堆转储以及如何组织数据。

    从左侧的菜单中,选择要检查的堆:

    • Default heap:系统未指定堆时。
    • App heap:您的应用在其中分配内存的主堆[primary heap]。
    • Image heap:系统启动映像[system boot image],包含启动期间预加载[preloaded]的类。 此处的分配保证绝不会移动或消失。
    • Zygote heap:copy-on-write heap,其中的应用进程是从 Android 系统中派生[forked]的。

    从右侧菜单中选择如何排列分配:

    • Arrange by class:基于类名称对所有分配进行分组。
    • Arrange by package:基于软件包名称对所有分配进行分组。
    • Arrange by callstack:将所有分配分组到其对应的调用堆栈。此选项仅在记录分配[recording allocations]期间捕获堆转储[capture the heap dump]时才有效。即使如此,堆中的对象也很可能是在您开始记录之前分配的,因此这些分配会首先显示,且只按类名称列出。

    默认情况下,此列表按 Retained Size 列排序。 您可以点击任意列标题以更改列表的排序方式。

    Instance View 中,每个实例都包含以下信息:

    • Depth:从任意 GC root 到所选实例的最短 hops 数。
    • Native Size: native内存中此实例的大小。此列仅适用于Android 7.0及更高版本。
    • Shallow Size:此实例Java内存的大小。
    • Retained Size:此实例支配[dominator]的内存大小(根据 [dominator 树](https://en.wikipedia.org/wiki/Dominator_(graph_theory))。

    默认情况下,堆转储_不会_向您显示每个已分配对象的堆叠追踪。 要获取堆叠追踪,在点击 Dump Java heap 之前,您必须先开始 记录内存分配。 然后,您可以在 Instance View 中选择一个实例,并查看 Call Stack 标签以及 References 标签,如图 5 所示。不过,在您开始记录分配之前,可能已分配一些对象,因此,调用堆栈不能用于这些对象。 包含调用堆栈的实例在图标 上用一个“堆栈”标志表示。(遗憾的是,由于堆叠追踪需要您执行分配记录,因此,您目前无法在 Android 8.0 上查看堆转储的堆叠追踪。)

    图 5. 捕获堆转储需要的持续时间标示在时间线中

    要检查您的堆,请按以下步骤操作:

    1、浏览列表以查找堆计数[heap counts]异常大且可能存在泄漏的对象。 为帮助查找已知类,点击 Class Name 列标题以按字母顺序排序。 然后点击一个类名称。 此时在右侧将出现 Instance View 窗格,显示该类的每个实例,如图 5 中所示。

    或者,您可以通过单击 Filter 或按 Control + F 并在搜索字段中输入类名或包名来快速定位对象。 也可以从下拉菜单中选择 Arrange by callstack 来按方法名称搜索。如果要使用正则表达式,请选中Regex旁边的框。如果您的搜索查询区分大小写,请选中匹配大小写旁边的框。

    2、在 Instance View 窗格中,点击一个实例。此时下方将出现 References,显示该对象的每个引用。或者,点击实例名称旁的箭头以查看其所有字段,然后点击一个字段名称查看其所有引用。 如果您要查看某个字段的实例详情,右键点击该字段并选择 Go to Instance

    3、在 References 标签中,如果您发现某个引用可能在泄漏内存,则右键点击它并选择 Go to Instance。 这将从堆转储中选择对应的实例,显示您自己的实例数据。

    在您的堆转储中,请注意由下列任意情况引起的内存泄漏:

    • 长时间引用 ActivityContextViewDrawable 和其他对象,可能会保持对 ActivityContext容器的引用。
    • 可以保持 Activity 实例的非静态内部类,如 Runnable
    • 对象保持时间超出所需时间的缓存。

    将堆转储另存为 HPROF

    在捕获堆转储后,仅当分析器运行时才能在 Memory Profiler 中查看数据。 当您退出分析会话时,您将丢失堆转储。 因此,如果您要保存堆转储以供日后查看,可通过点击时间线下方工具栏中的 Export heap dump as HPROF file,将堆转储导出到一个 HPROF 文件中。 在显示的对话框中,确保使用 .hprof 后缀保存文件。

    然后,通过将此文件拖到一个空的编辑器窗口(或将其拖到文件标签栏中),您可以在 Android Studio 中重新打开该文件。

    要使用其他 HPROF 分析器(如 jhat),您需要将 HPROF 文件从 Android 格式转换为 Java SE HPROF 格式。 您可以使用 android_sdk/platform-tools/ 目录中提供的 hprof-conv 工具执行此操作。 运行包括以下两个参数的 hprof-conv 命令:原始 HPROF 文件和转换后 HPROF 文件的写入位置。 例如:

    hprof-conv heap-original.hprof heap-converted.hprof

    导入堆转储文件
    要导入HPROF(.hprof)文件,请单击 Sessions 窗格中 Load from file,然后从文件浏览器中选择该文件。

    您还可以通过将 HPROF 文件从文件浏览器拖到编辑器窗口中来导入HPROF文件。

    分析内存的技巧

    使用 Memory Profiler 时,您应对应用代码施加压力[stress your app code]并尝试强制内存泄漏。在应用中引发内存泄漏的一种方式是,先让其运行一段时间,然后再检查堆。泄漏在堆中可能逐渐汇聚到分配顶部[Leaks might trickle up to the top of the allocations in the heap]。不过,泄漏越小,您越需要运行更长时间才能看到泄漏。

    您还可以通过以下方式之一触发内存泄漏:

    • 将设备从纵向旋转为横向,然后在不同的 Activity 状态下反复操作多次。 旋转设备经常会导致应用泄漏 Activity、Context、View 对象,因为系统会重新创建 Activity,而如果您的应用在其他地方保持对这些对象之一的引用,系统将无法对其进行垃圾回收。
    • 处于不同的 Activity 状态时,在您的应用与另一个应用之间切换(导航到主屏幕,然后返回到您的应用)。

    提示:您还可以使 用monkeyrunner 测试框架执行上述步骤。

    MAT 工具详解

    参考1
    参考2

    MAT,Memory Analyzer Tool,一个基于Eclipse的免费内存分析工具,是一个快速、功能丰富的 JAVA heap 分析工具,它可以帮助我们查找内存泄漏和查看内存消耗情况。使用内存分析工具从众多的对象中进行分析,快速的计算出在内存中对象的占用大小,看看是谁阻止了垃圾收集器的回收工作,并可以通过报表直观的查看到可能造成这种结果的对象。

    当然 MAT 也有独立的不依赖 Eclipse 的版本,只不过这个版本在调试 Android 内存的时候,需要将 DDMS 生成的文件进行转换,才可以在独立版本的 MAT 上打开。不过 Android SDK 中已经提供了这个工具,所以使用起来也是很方便的。

    MAT工具提供了三种选择的方式:

    • Update Site:在线安装Eclipse插件的方式
    • Archived Update Site:离线安装Eclipse插件的方式
    • Stand-alone Eclipse RCP Applications:独立安装方,1.8.0 独立安装版下载地址

    获取及打开 .hprof 文件

    使用MAT既可以打开一个已有的堆快照,也可以通过MAT直接从活动Java程序中导出堆快照。

    HPROF文件是MAT能识别的文件,HPROF文件存储的是特定时间点,java进程的内存快照。有不同的格式来存储这些数据,总的来说包含了快照被触发时java对象和类在heap中的情况。由于快照只是一瞬间的事情,所以heap dump中无法包含一个对象在何时、何地(哪个方法中)被分配这样的信息。

    这个文件可以使用DDMS导出:DDMS中在Devices上面有一排按钮,选择一个进程后,点击Dump HPROF file 按钮,选择存储路径保存后就可以得到对应进程的HPROF文件。eclipse插件可以把上面的工作一键完成。只需要点击Dump HPROF file图标,然后MAT插件就会自动转换格式,并且在eclipse中打开分析结果。

    在使用使用Eclipse或者AndroidStudio抓内存之前,一定要手动点击 Initiate GC 按钮手动触发GC,这样抓到的内存使用情况就是不包括Unreachable对象的。
    Unreachable指的是可以被垃圾回收器回收的对象,但是由于没有GC发生,所以没有释放,这时抓的内存使用中的Unreachable就是这些对象。
    点击Calculate Retained Size之后,会出现Retained Size这一列,可以看到Unreachable Object的对象其Retained Heap值都为0。

    如果HPROF文件是通过AndroidStudio的profile工具导出的,由于这个不是 mat 工具用到的标准文件,我们需要使用 sdk 自带的platform-tools/hprof-conv.exe工具进行转换,命令为:

    hprof-conv -z 1.hprof 1_mat.hprof

    转换过后的.hprof文件即可使用MAT工具打开了。

    打开一个.hprof文件时,首先会显示Getting Start Wizard向导弹框,默认会选择了第一个,确定后会生成一个报告。这个无大碍。

    注意:最好将.hprof文件放在一个单独的文件夹内打开,因为你在操作过程中,会生成大量的临时文件。

    工具栏

    • Overview:主界面
    • Histogram:直方图
    • Dominator Tree:支配树
    • OQL:Object Query Language studio
    • Thread OvewView:查看这个应用所有的Thread信息

    • Run Expert System Test:运行专家系统测试
    • Query Browser:查询浏览器
    • Find Object By Address

    • Group:在Histogram和Domiantor Tree界面,可以选择将结果用另一种Group的方式显示(默认是Group by Object),切换到Group by package可以更好地查看具体是哪个包里的类占用内存大,也很容易定位到自己的应用程序。

    • Calculate Retained Size:点击后,会出现Retained Size这一列

    主界面 Overview

    我们需要关注的是下面Actions区域,介绍4种分析方法:

    • Histogram: Lists number of instances per class 列出内存中的对象,对象的个数以及大小
    • Dominator Tree: List the biggest objects and what they keep alive. 列出最大的对象以及其依赖存活的Object,大小是以Retained Heap为标准排序的
    • Top Consumers: Print the most expensive objects grouped by class and by package. 通过图形列出最大的object
    • Duplicate Classes: Detect classes loaded by multiple class loaders. 通过MAT自动分析泄漏的原因

    default_report 窗口

    该窗口列出了可能有问题的代码片段。点击每个问题中的Details可以查看相关的详情。

    详情页面包含如下内容

    • Description:问题简要描述
    • Shortest Paths To the Accumulation Point:在此列表中,我们可以追溯到问题代码的类树的结构,并找到自己代码中的类。
    • Accumulated Objects in Dominator Tree:在此列表中,我们可以看见创建的大量的对象
    • Accumulated Objects by Class in Dominator Tree:在此列表中,我们能看见创建大量对象相关的类。
    • All Accumulated Objects by Class:在此列表中,会按类别划分的所有累计对象。

    两个重要概念

    Shallow heap:本身占用内存

    Shallow size就是对象本身占用内存的大小,不包含其引用的对象。

    • 常规对象(非数组)的Shallow size由其成员变量的数量和类型决定
    • 数组类型的对象的shallow size由数组元素的类型(对象类型、基本类型)和数组长度决定

    注意:因为不像c++的对象本身可以存放大量内存,java的对象成员都是些引用。真正的内存都在堆上,看起来是一堆原生的byte[]char[]int[],所以我们如果只看对象本身的内存,那么数量都很小。所以我们看到 Histogram 图是以Shallow size进行排序的,排在第一位的一般都是byte[]

    Retained Heap:引用占用内存

    Retained Heap的概念,它表示如果一个对象被释放掉,那么该对象引用的所有对象,包括被递归引用的对象,被释放的内存。

    例如,如果一个对象的某个成员new了一大块int数组,那这个int数组也可以计算到这个对象中。与shallow heap比较,Retained heap可以更精确的反映一个对象实际占用的大小,因为如果该对象释放,retained heap都可以被释放。

    但是,Retained Heap并不总是那么有效。
    例如,我在A里new了一块内存,赋值给A的一个成员变量,同时我让B也指向这块内存。此时,因为A和B都引用到这块内存,所以A释放时,该内存不会被释放。所以这块内存不会被计算到A或者B的Retained Heap中。

    为了纠正这点,MAT中的 Leading Object(例如A或者B)不一定只是一个对象,也可以是多个对象。此时,(A,B)这个组合的Retained Set就包含那块大内存了。对应到MAT的UI中,在Histogram中,可以选择 Group By class, superclass or package来选择这个组。


    为了计算Retained Memory,MAT引入了Dominator Tree。

    例如,对象A引用B和C,B和C又都引用到D,计算Retained Memory时:

    • A的包括A本身和B,C,D。
    • B和C因为共同引用D,所以B,C 的Retained Memory都只是他们本身。
    • D当然也只是自己。

    在这里例子中,树根是A,而B,C,D是他的三个儿子,B,C,D不再有相互关系。

    我觉得是为了加快计算的速度,MAT将对象引用图转换成对象引用树。把引用图变成引用树后,计算Retained Heap就会非常方便,显示也非常方便。对应到 MAT UI 上,在 dominator tree 这个view中,显示了每个对象的 shallow heap 和 retained heap。然后可以以该节点为树根,一步步的细化看看 retained heap 到底是用在什么地方了。

    这种从图到树的转换确实方便了内存分析,但有时候会让人有些疑惑。本来对象B是对象A的一个成员,但因为B还被C引用,所以B在树中并不在A下面,而很可能是平级。

    为了纠正这点,MAT中点击右键,可以 List objects 中选择 with outgoing references 和 with incoming references。这是个真正的引用图的概念,

    • outgoing references :表示该对象的出节点(被该对象引用的对象)
    • incoming references :表示该对象的入节点(引用到该对象的对象)

    为了更好地理解 Retained Heap,下面引用一个例子来说明:

    把内存中的对象看成下图中的节点,并且对象和对象之间互相引用。这里有一个特殊的节点GC Roots,这就是reference chain(引用链)的起点:

    上图中蓝色节点代表仅仅只有通过obj1才能直接或间接访问的对象。因为可以通过GC Roots访问,所以上图的obj3不是蓝色节点。因此上图中obj1的retained size是obj1、obj2、obj4的shallow size总和。


    上图obj1的retained size是obj1、obj2、obj3、obj4的shallow size总和。而obj2的retained size是obj3、obj4的shallow size总和。

    Histogram 和 Dominator Tree

    Histogram的主要作用是查看一个instance的数量,一般用来查看自己创建的类的实例的个数。

    可以很容易的找出占用内存最多的几个对象,根据百分比(Percentage)来排序。

    可以分不同维度来查看对象的Dominator Tree视图,Group by class、Group by class loader、Group by package

    Dominator Tree和Histogram的区别是站的角度不一样,Histogram是站在的角度上去看,Dominator Tree是站的对象实例的角度上看,Dominator Tree可以更方便的看出其引用关系。

    通过查看Object的个数,结合代码就可以找出存在内存泄露的类(即可达但是无用的对象,或者是可以重用但是重新创建的对象)

    Histogram中还可以对对象进行Group,更方便查看自己Package中的对象信息。

    右键菜单:Query Browser

    菜单名称 子选项 描述
    List objects With Outgoing References 显示选中对象持有哪些对象
    With Incoming References 显示选中对象被哪些对象持有。如果一个类有很多不需要的实例,那么可以找到哪些对象持有该对象,让这个对象没法被回收。
    Show objects by class With Outgoing References 显示选中对象持有哪些对象, 这些对象按类合并在一起排序
    With Incoming References 显示选中对象被哪些对象持有,这些对象按类合并在一起排序
    Merge Shortest Paths to GC Roots. 从GC Roots节点到该对象的最短引用路径
    With all references 显示选中对象到GC根节点的引用路径,包括所有类型引用。
    Exclude weak/soft/phantom references 排除了弱/软/虚引用

    菜单名称 子选项 描述
    Java Basics References Statistics 显示引用和对象的统计信息
    Class Loader Explorer 列出类加载器,包括定义的类
    Customized Retained Set 计算选中对象的保留堆,排除指定的引用
    Find Strings
    Group By Value
    Open in Dominator Tree 对选中对象生成支配树
    Show as Histogram 展示任意对象的直方图
    Thread Details 显示线程的详细信息和属性
    Thread Overview and Stacks -

    菜单名称 子选项 描述
    Java Collections Array Fill Ratio 输出给定数组中,非基本类型、非null对象个数占比
    Arrays Grouped by Size 显示数组的直方图,按大小分组
    Collection Fill Ratio 输出给定集合中,非基本类型、非 null 对象个数占比
    Collections Grouped by Size 显示集合的直方图,按大小分组
    Hash Entries 展开显示指定HashMap或Hashtable中的键值对
    Map Collision Ratio 输出指定的映射集合的碰撞率
    Primitive Arrays With a Constant Value 列出基本数据类型的数组,这些数组是由一个常数填充的
    Leak Identification Component Report 展示组件报告,分析可能的内存浪费或者低效使用的组件
    Top Consumers 输出内存浪费最大的那个组件

    Search Queries:搜索列出所有Queries选项的具体含义,包含搜索区、输入关键字后匹配的Queries选项列表区,点击选项后的具体含义解释区。

    可以看到,所有的命令其实就是配置不同的SQL查询语句,比如我们最常用的:

    • List objects -> with incoming references:查看这个对象持有的外部对象引用
    • List objects -> with outcoming references:查看这个对象被哪些外部对象引用
    • Path To GC Roots -> exclude all phantim/weak/soft etc. references:查看这个对象的GC Root,不包含虚、弱引用、软引用,剩下的就是强引用。从GC上说,除了强引用外,其他的引用在JVM需要的情况下是都可以 被GC掉的,如果一个对象始终无法被GC,就是因为强引用的存在,从而导致在GC的过程中一直得不到回收,因此就内存溢出了。
    • Merge Shortest path to GC root:找到从GC根节点到一个对象或一组对象的共同路径

    2019-3-20

    转载于:https://www.cnblogs.com/baiqiantao/p/10575841.html

    展开全文
  • 对于内存泄漏,在Android中如果不注意的话,还是很容易出现的,尤其是在Activity中,比较容易出现,下面我就说下自己是如何查找内存泄露的。 首先什么是内存泄漏内存泄漏就是一些已经不使用的对象还存在于...
  • 内存泄漏是一些已经不使用的对象,依然占有内存且垃圾回收机制不法回收它们。最终导致 常驻内存越来越大 ,影响到程序的性能。 在Android 虚拟机中,采用Mark-Sweep方式实现垃圾回收。Mark标记,Sweep检测。...
  • JVM系列文章目录 初识JVM 深入理解JVM内存区域 玩转JVM对象和引用 JVM分代回收机制和垃圾回收算法 细谈JVM垃圾回收与部分底层实现 ...玩转MAT分析内存泄漏JVM系列文章目录前言MAT概要柱状视图MAT内存泄漏分析
  • 主要介绍了Android Studio+MAT实战内存泄漏的相关技术内容,并在需要注意的地方做了提示,需要参考学习下吧。
  • Android使用MAT查找内存泄漏-附件资源
  • Mat分析内存泄漏

    2015-11-18 16:05:48
    1最原始的内存泄露测试 重复多次操作关键的可疑的路径,从内存监控工具中观察内存曲线,是否存在...2MAT内存分析工具 2.1 MAT分析heap的总内存占用大小来初步判断是否存在泄露 在Devices 中,点击
  • android使用mat分析内存泄漏

    千次阅读 2014-12-12 17:45:38
    android使用mat分析内存泄漏
  • MAT 分析内存泄漏

    2020-09-27 19:01:33
    比较容易分析的问题,我们可以使用jmap -histo这种命令去分析哪些对象占据着我们的堆空间,如果是遇到内存情况比较复杂的情况,命令的方式是看不出来的,这时我们就须要借助一下工具,前提是通过jmap命令把整个堆...
  • 使用MAT分析内存泄漏

    2020-01-10 09:20:05
    利用内存分析工具(Memory Analyzer Tool,MAT)分析java项目内存泄露 一、开发环境: 操作系统:ubuntu 14.04 IDE:Eclipse Java EE IDE for Web Developers.Version: Luna Service Release 2 (4.4.2) JDK版本...
  • MAT分析内存泄漏

    2016-05-13 16:21:37
    MAT常用的功能: Histogram可以列出内存中每个对象的名字、数量以及大小。 Dominator Tree会将所有内存中的对象按大小进行排序,并且我们可以分析对象之间的引用结构。 摘取: 这是Dominator Tree中比较...
  • 使用MAT 检测内存泄漏

    2016-03-24 17:25:01
    要分析内存泄漏,首先要了解内存使用情况,这就需要专门的工具来协助。首先要产生内存使用情况的文件(.hprof),其次用工具(MAT)来分析即可。   android studio 和eclipse 都可以 产生 app内存使用情况的文件。...
  • 全名是 Memory Analyzer是一个快速且功能丰富的Java堆分析器,可帮助您查找内存泄漏并减少内存消耗。官网地址 下载地址 MemoryAnalyzer-1.9.0.20190605-win32.win32.x86_64密码:scih MemoryAnalyzer-1.9.0.20190605-...
  • square 公司出品 ...两天,一个内存泄漏 activity 泄漏 ,搞了两天。毕竟是有开发经验的程序员,工作时间久了,你说你没有用过mat?没有过内存优化分析,内存泄漏研究? 呵呵。 第一步:使用st...
  • 玩转MAT分析内存泄漏

    2020-09-05 16:45:36
    MAT 工具是基于 Eclipse 平台开发的,本身是一个 Java 程序,是一款很好的内存分析工具,所以如果你的堆快照比较大的话,则需要一台内存比较大的分析机器,并给 MAT 本身加大初始内存,这个可以修改安装目录中的 ...
  • 点击打开链接对于内存泄漏,在Android中如果不注意的话,还是很容易出现的,尤其是在Activity中,比较容易出现,下面我就说下自己是如何查找内存泄露的。首先什么是内存泄漏内存泄漏就是一些已经不使用的对象还...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,279
精华内容 511
关键字:

mat内存泄漏