热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

MemoryProfiler实用篇

1.简介MemoryProfiler是AndroidProfiler中的一个组件,可帮助您识别因内存泄漏和内存抖动导致的卡顿,无响应,甚至crashes。它显示了应用程序内存使用的

1. 简介

Memory Profiler是Android Profiler中的一个组件 ,可帮助您识别因内存泄漏和内存抖动导致的卡顿,无响应,甚至crashes。它显示了应用程序内存使用的实时图形,可以捕获堆信息,强制GC以及跟踪内存分配。我们使用Memory Profiler执行以下操作:



  • 在时间轴中寻找可能导致性能问题的不良内存分配模式。



  • dump Java heap查看在任何给定时间哪些对象正在使用内存。在一段时间内Several heap dumps可以帮助识别内存泄漏。



  • 在正常和极端的用户交互过程中记录内存分配,以确定代码在短时间内分配太多对象或分配泄漏对象的位置。




2. 概述



  • 默认图

    打开Memory Profiler,你会看到你的应用程序的内存使用和访问工具的详细时间表,强制垃圾收集,heap dump,并记录内存分配。



  • 标号解析

    标号1:强制GC按钮。

    标号2:堆内存快照。

    标号3:内存分配录制按钮,此功能只出现在Android7.1及更低版本。

    标号4:时间轴缩放按钮。

    标号5:跳转到实时内存数据显示的按钮。

    标号6:event 时间轴,显示activity状态, user input events, and screen rotation events.

    标号7:内存使用时间轴。(包含每个内存类别使用多少内存的堆栈图,如左侧的y轴和顶部的颜色键所示;虚线表示分配对象的数量,如右边的y轴所示;每个垃圾收集事件的图标。)




3. 内存是如何计算的



  • 图例



  • 类别解析

    Java:从Java或Kotlin代码分配的对象的内存。

    Native:从C或C ++代码分配的对象的内存。

    Graphics:用于图形缓冲区队列的内存,用于在屏幕上显示像素,包括GL表面,GL纹理等。(请注意,这是与CPU共享的内存,不是专用的GPU内存。)

    Stack:您的应用中的native和Java堆栈使用的内存。这通常与您的应用程序运行的线程数有关。

    Code:您的应用程序使用代码和资源的内存,如dex字节码,优化或编译的dex代码,.so库和字体。

    Other:你的应用程序使用的内存,系统不知道如何分类。

    Allocated:您的应用程序分配的Java / Kotlin对象的数量。这不会计算以C或C ++分配的对象。





    • 当连接到运行Android 7.1及更低版本的设备时,只有当Memory Profiler连接到正在运行的应用程序时,才会启动此分配计数。因此,在开始分 析之前分配的任何对象都不会被计入。但是,Android 8.0包含一个设备分析工具,可以跟踪所有分配情况,因此这个数字总是表示Android 8.0及更高版本上应用程序中未完成Java对象的总数。



    • 与以前的Android监视器工具的内存计数相比,新的内存分析器以不同的方式记录您的内存,因此您的内存使用似乎更高。Memory Profiler监视一些增加总数的额外类别,但是如果您只关心Java堆内存,那么“Java”数字应该类似于上一个工具的值。






4. 查看内存分配

内存分配显示你的内存中的每个对象是如何分配的。具体来说,内存分析器可以显示以下关于对象分配的内容:



  • 分配了什么类型的对象以及它们使用了多少空间。



  • 每个分配的堆栈跟踪,包括哪个线程。



  • 解除分配对象时(仅在使用Android 8.0或更高版本的设备时)。



如果您的设备运行的是Android 8.0或更高版本,则可以随时查看对象分配,如下所示:只需在时间轴上单击并按住,然后拖动以选择要查看分配的区域(如视频1所示)。没有必要开始录制会话,因为Android 8.0和更高版本包括一个设备上的分析工具,不断跟踪你的应用程序的分配。

如果您的设备运行的是Android 7.1或更低版本,请单击Memory Profiler工具栏中的记录内存分配 。在录制期间,Android监控器会跟踪您应用中发生的所有分配情况。完成后,单击 停止录制 (同一按钮;请参阅视频2)查看分配。

检查分配记录,请按照下列步骤操作:



  • 浏览列表以查找具有异常大堆计数并可能泄漏的对象。为帮助查找已知类,请单击“ 类名” 列标题按字母顺序排序。然后点击一个类名。该 实例的查看窗格显示在右侧,显示出类的每个实例。



  • 在“ Instance View”窗格中,单击一个实例。“ Call Stack”选项卡显示在下面,显示实例被分配的位置以及在哪个线程中。



  • 在“ Call Stack”选项卡中,单击任何行以跳转到编辑器中的代码。




5. 查看heap信息

heap dump捕获应用程序中的哪些对象正在使用内存。特别是在扩展user session之后,heap dump识别内存泄漏。查看以下内容:



  • 应用分配了哪些类型的对象,以及每个对象的数量。



  • 每个对象使用多少内存。



  • 每个对象的引用都在代码的什么地方。



  • 调用堆栈分配对象的位置。



heap dump时Java内存量可能会暂时增加。这是正常的,因为heap dump发生在与您的应用程序相同的进程,并需要一些内存来收集数据。

字段解析:

Alloc Count:堆中的分配数量。

Native Size:此对象类型使用的本机内存总量(以字节为单位)。此列仅适用于Android 7.0及更高版本。

你会在这里看到一些在Java中分配的对象的内存,因为Android为一些框架类使用本地内存,比如Bitmap。

Shallow Size:此对象类型使用的Java内存总量(以字节为单位)。

Retained Size:由于此类的所有实例而保留的内存总大小(以字节为单位)。

在班级列表顶部,您可以使用左侧的下拉列表在下列堆转储之间切换:

Default heap:当系统没有指定堆时。

App heap:应用程序分配内存的主要堆。

Image heap:系统引导映像,包含在引导期间预加载的类。这里的分配保证不会移动或消失。

Zygote heap:Android系统中的应用程序进程分支的写入时复制堆。

堆中的对象列表按类名排列,默认情况下。您可以使用另一个下拉菜单在以下安排之间切换:

Arrange by class:根据类名称对所有分配进行分组。

Arrange by package:根据包名分组所有分配。

Arrange by callstack:将所有分配分组到相应的调用堆栈中。只有在录制分配时捕获堆转储时,此选项才有效。即使如此,在开始录制之前堆中可能会有一些对象,所以这些分配首先出现,只是按类名称列出。

检查堆,请按照下列步骤操作:



  • 浏览列表以查找具有异常大堆计数并可能泄漏的对象。为帮助查找已知类,请单击“ Class Name” 列标题按字母顺序排序。然后点击一个类名。该 Instance View的查看窗格显示在右侧,显示出类的每个实例。



  • Instance View单击一个实例。“ References ” 选项卡显示在下方,显示对该对象的每个引用。



  • 在“ References”选项卡中,如果您确定可能正在泄漏内存的引用,请右键单击它并选择“ Go to Instance”。这将从堆转储中选择相应的实例,向您显示其自己的实例数据。




6. 保存heap为HPROF

一旦 capture a heap dump,只有在分析器正在运行时,才能在Memory Profiler中查看数据。当您退出分析会话时,会丢失。如果稍后想要保存以供稍后查看,请通过单击时间线下面的工具栏中的Export capture to file导出到HPROF文件。HPROF可以用Android Studio重新打开,如果用其他分析器需要 android_sdk/platform-tools/hprof-conv 转换才可以。


7. 使用技巧

使用Memory Profiler时,应该stress your app code并尝试强制内存泄漏。在应用程序中引发内存泄漏的一种方法是在检查堆之前让它运行一段时间。泄漏可能会溢出到堆中分配的顶部。但是,泄漏越小,运行应用程序以查看它所需的时间就越长。

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



  • 在不同的活动状态下,将设备从纵向旋转到横向并再次旋转多次。旋转设备往往会导致应用程序泄漏的 Activity, Context或 View因为系统重新创建对象Activity,如果您的应用程序拥有对这些对象的其他地方的一个参照,系统无法垃圾收集。



  • 在不同的活动状态下切换您的应用程序和另一个应用程序(导航到主屏幕,然后返回到您的应用程序)。




8. references

View the Java Heap and Memory Allocations with Memory Profiler



推荐阅读
  • Google Play推出全新的应用内评价API,帮助开发者获取更多优质用户反馈。用户每天在Google Play上发表数百万条评论,这有助于开发者了解用户喜好和改进需求。开发者可以选择在适当的时间请求用户撰写评论,以获得全面而有用的反馈。全新应用内评价功能让用户无需返回应用详情页面即可发表评论,提升用户体验。 ... [详细]
  • Tomcat/Jetty为何选择扩展线程池而不是使用JDK原生线程池?
    本文探讨了Tomcat和Jetty选择扩展线程池而不是使用JDK原生线程池的原因。通过比较IO密集型任务和CPU密集型任务的特点,解释了为何Tomcat和Jetty需要扩展线程池来提高并发度和任务处理速度。同时,介绍了JDK原生线程池的工作流程。 ... [详细]
  • Oracle10g备份导入的方法及注意事项
    本文介绍了使用Oracle10g进行备份导入的方法及相关注意事项,同时还介绍了2019年独角兽企业重金招聘Python工程师的标准。内容包括导出exp命令、删用户、创建数据库、授权等操作,以及导入imp命令的使用。详细介绍了导入时的参数设置,如full、ignore、buffer、commit、feedback等。转载来源于https://my.oschina.net/u/1767754/blog/377593。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • Java在运行已编译完成的类时,是通过java虚拟机来装载和执行的,java虚拟机通过操作系统命令JAVA_HOMEbinjava–option来启 ... [详细]
  • Oracle优化新常态的五大禁止及其性能隐患
    本文介绍了Oracle优化新常态中的五大禁止措施,包括禁止外键、禁止视图、禁止触发器、禁止存储过程和禁止JOB,并分析了这些禁止措施可能带来的性能隐患。文章还讨论了这些禁止措施在C/S架构和B/S架构中的不同应用情况,并提出了解决方案。 ... [详细]
  • Android工程师面试准备及设计模式使用场景
    本文介绍了Android工程师面试准备的经验,包括面试流程和重点准备内容。同时,还介绍了建造者模式的使用场景,以及在Android开发中的具体应用。 ... [详细]
  • 如何用JNI技术调用Java接口以及提高Java性能的详解
    本文介绍了如何使用JNI技术调用Java接口,并详细解析了如何通过JNI技术提高Java的性能。同时还讨论了JNI调用Java的private方法、Java开发中使用JNI技术的情况以及使用Java的JNI技术调用C++时的运行效率问题。文章还介绍了JNIEnv类型的使用方法,包括创建Java对象、调用Java对象的方法、获取Java对象的属性等操作。 ... [详细]
  • 恶意软件分析的最佳编程语言及其应用
    本文介绍了学习恶意软件分析和逆向工程领域时最适合的编程语言,并重点讨论了Python的优点。Python是一种解释型、多用途的语言,具有可读性高、可快速开发、易于学习的特点。作者分享了在本地恶意软件分析中使用Python的经验,包括快速复制恶意软件组件以更好地理解其工作。此外,作者还提到了Python的跨平台优势,使得在不同操作系统上运行代码变得更加方便。 ... [详细]
  • 猜字母游戏
    猜字母游戏猜字母游戏——设计数据结构猜字母游戏——设计程序结构猜字母游戏——实现字母生成方法猜字母游戏——实现字母检测方法猜字母游戏——实现主方法1猜字母游戏——设计数据结构1.1 ... [详细]
  • 重入锁(ReentrantLock)学习及实现原理
    本文介绍了重入锁(ReentrantLock)的学习及实现原理。在学习synchronized的基础上,重入锁提供了更多的灵活性和功能。文章详细介绍了重入锁的特性、使用方法和实现原理,并提供了类图和测试代码供读者参考。重入锁支持重入和公平与非公平两种实现方式,通过对比和分析,读者可以更好地理解和应用重入锁。 ... [详细]
  • 如何在php文件中添加图片?
    本文详细解答了如何在php文件中添加图片的问题,包括插入图片的代码、使用PHPword在载入模板中插入图片的方法,以及使用gd库生成不同类型的图像文件的示例。同时还介绍了如何生成一个正方形文件的步骤。希望对大家有所帮助。 ... [详细]
  • Asp.net Mvc Framework 七 (Filter及其执行顺序) 的应用示例
    本文介绍了在Asp.net Mvc中应用Filter功能进行登录判断、用户权限控制、输出缓存、防盗链、防蜘蛛、本地化设置等操作的示例,并解释了Filter的执行顺序。通过示例代码,详细说明了如何使用Filter来实现这些功能。 ... [详细]
  • 本文介绍了在Android开发中使用软引用和弱引用的应用。如果一个对象只具有软引用,那么只有在内存不够的情况下才会被回收,可以用来实现内存敏感的高速缓存;而如果一个对象只具有弱引用,不管内存是否足够,都会被垃圾回收器回收。软引用和弱引用还可以与引用队列联合使用,当被引用的对象被回收时,会将引用加入到关联的引用队列中。软引用和弱引用的根本区别在于生命周期的长短,弱引用的对象可能随时被回收,而软引用的对象只有在内存不够时才会被回收。 ... [详细]
  • MySQL数据库锁机制及其应用(数据库锁的概念)
    本文介绍了MySQL数据库锁机制及其应用。数据库锁是计算机协调多个进程或线程并发访问某一资源的机制,在数据库中,数据是一种供许多用户共享的资源,如何保证数据并发访问的一致性和有效性是数据库必须解决的问题。MySQL的锁机制相对简单,不同的存储引擎支持不同的锁机制,主要包括表级锁、行级锁和页面锁。本文详细介绍了MySQL表级锁的锁模式和特点,以及行级锁和页面锁的特点和应用场景。同时还讨论了锁冲突对数据库并发访问性能的影响。 ... [详细]
author-avatar
的士风云
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有