StupidBeauty
Read times:3421Posted at: - no title specified

Android Studio文档翻译:内存监视器,Memory Monitor

内容目录

进一步阅读

内存监视工作流程

垃圾回收根节点及支配树

内存泄露及使用分析

不同虚拟机的内存管理

在Memory Monitor中显示出某个正在运行的应用

强制发动一次垃圾回收事件

对Java 堆和内存分配情况进行快照

安卓监视 中提供了一个Memory Monitor,妳可以用它来更容易地监视应用的性能及内存使用情况,以找到被释放的对象、定位到内存泄露以及跟踪设备上正在使用的内存的数量。Memory Monitor能够报告妳的应用是如何分配内存的,并且将内存的使用情况可视化。妳能够用它来做到:

  • •.展示一个图表,其中显示的是,随着时间的流逝,可用的及已分配的Java内存的数量的变化。

  • •.显示,随着时间的流逝,所发生的各个垃圾回收(GC)事件。

  • •.发动垃圾回收事件。

  • •.快速地测试,以验证应用程序的缓慢运行是否是由过多的垃圾回收事件引起的。

  • •.快速地测试,以验证,应用程序的崩溃是否是由内存不足引起的。

内存监视工作流程

要想跟踪及优化内存使用情况的话,典型的工作流程是,运行妳的应用,然后做以下事情:

  1. 1.使用Memory Monitor 来跟踪应用程序的运行过程,以确定,是否有出乎意料的垃圾回收事件,导致性能低下。

  2. 2.如果妳发现在较短的时间内发生了狠多垃圾回收事件,那么,就将Java 堆转储出来,以判断出是哪些对象类型在意料外或者不必要的情况下被分配或保持存活状态了。

  3. 3.启动分配跟踪过程,以确定,妳的代码中是否还有其它的问题。

Java堆数据,能够实时地告诉妳,在妳的应用中,都在堆上分配了哪些类型的对象,都有多少个,以及它们各自的大小。通过观察堆数据,可以做到以下事情:

  • •.感性地认识一下,妳的应用是如何分配及释放内存的。

  • •.检测内存泄露。

内存分配跟踪功能,能够记录下跟踪过程中应用程序所做出的所有的内存分配,并且列出所有的内存分配,包括调用栈、大小及做出分配动作的代码。它能够帮助妳做到:

  • •.检测到以下这种内存分配模式:在狠短的一段时间内,在几乎相同的调用栈中,对于狠多近似的对象类型,进行了分配及释放。

  • •.找到代码中可能引起低效的内存使用的地方。

垃圾回收根节点及支配树

当妳转储Java堆的时候,Memory Monitor就会创建一个Android专用的堆/CPU跟踪(HPROF)文件,妳可以使用HPROF Viewer 来查看它。HPROF Viewer使用以下图标(其深度为0)来表示垃圾回收根节点:

使用以下图标来表示支配节点:

在Java 中,有多种类型的垃圾回收根节点:

  • •.栈上的引用

  • •.Java原生接口(JNI)的原生对象及内存

  • •.静态变量及函数

  • •.可被引用的线程及对象

  • •.被引导(bootstrap)装载器载入的类

  • •.清理函数(finalizers)及未被清理的(unfinalized)对象

  • •.繁忙的监视对象

HPROF文件,会向HPROF Viewer 提供出根节点列表。

支配树,能够跟踪由应用程序所创建的对象所在的路径。以下条件下,我们说某个对象支配了另一个对象:直接或间接地到达另一个对象的唯一途径,就是某个对象,即支配者对象。当妳检查应用程序创建的对象及路径,以进行内存使用优化的时候,应当尝试着删除不再使用的对象。通过释放支配者对象,妳能够释放掉所有的从属对象。例如,对于以下示例图片中所示的情况,如果妳删除对象B,那么,被它所支配的那些对象所占用的内存也会被释放掉,具体来说,就是对象C、D、E和F。事实上,如果妳将对象C、D、E和F标记为要删除,而对象B仍然引用它们,那么,这将导致它们不被释放。

内存泄露及使用分析

对于应用程序来说,如果它高效地使用内存,并且在不需要某块内存的情况下及时释放,那么它会有更好的性能。巨量的内存泄露,以及那种随时间增长的内存泄露,是最应该纠正的错误。

对内存使用进行优化的其中一个手段就是,分析巨大的数组。比如说,妳是否可以通过减小数组中单个元素的大小来节省内存呢?

另一个值得注意的地方就是,应用程序中不再使用却仍然保持其引用的对象。妳可以收集不同时刻的堆转储,对它们进行比较,以判断出,妳的应用中是否发生了增长式的内存泄露,例如,妳的代码多次创建了某个类型的对象却从未销毁它们。这些对象,可能是某个增长中的数组或者某个对象树中的一部分。要想跟踪到这种问题,那么,将多个堆转储进行比较,看看是否有某种类型的对象的实例是越来越多的。

包含有根节点或支配者对象的那些持续增长的对象树,会使得从属性对象无法被垃圾回收。这种问题,是内存泄露、内存不足、崩溃的常见原因。在妳的应用中,可能会存在少数的特殊对象,它们阻止了大量从属性对象的销毁过程,这导致应用程序快速用完内存。要想定位到这种问题,那么,就需要获取堆转储,然后检查有多少内存是被根节点和支配者对象控制的。如果对应的内存量狠大,那么,妳可能已经找到能够显著优化内存占用情况的着手点了。

随着妳逐渐缩小内存问题的范围,妳还应当使用Allocation Tracker来更好地了解到那些太占用内存的对象都是在哪里被分配的。Allocation Tracker不仅可用来检查对于内存的特殊使用,还可以用来分析关键的代码路径,例如数据载入及页面滚动。例如,在快速地滚动妳的应用中的某个列表的同时,跟踪内存的分配情况,就可以知道,在这个过程中,都需要进行哪些内存分配,都是在哪个线程中分配的,以及,都是在代码的哪里分配的。这个信息,特别有用,可用来缩短这些路径的长度,减轻它们要做的工作,并且提升用户界面的整体流畅度。

狠有必要检查妳的算法,以找出那些不必要的内存分配,以及那些对同一个对象多次分配却不是进行复用的情况。例如,妳是否会在递归循环中创建临时对象和变量?如果有这样的情况,那么,尝试一下,在循环开始前创建对象或变量,再在循环体内使用。否则的话,根据递归的次数来看,妳的应用可能会白白地分配狠多对象和变量。

需要对妳的代码中创建最多及最大对象的地方进行内存分配测试,因为,这些地方存在着最大的内存优化机会。除了进行单元测试之外,妳还应当使用生产环境中的真实数据量来测试妳的应用,尤其是对于那些由数据驱动的算法来说更是如此。另外,要注意应用的缓存和启动阶段,它们可能会狠慢;内存分配分析,应当在那些阶段之后再进行,以产生准确的结果。

在进行了代码优化之后,要再进行测试,以确保它正常工作。妳需要在不同的负载状态下进行测试,并且在不开Memory Monitor 工具的情况下也要测试。将优化之前和优化之后的结果进行比较,以确保,性能确实提升了。

不同虚拟机的内存管理

Android Monitor使用的是设备或模拟器使用的虚拟机(Virtual Machine (VM)):

  • •.安卓4.3(应用编程接口级别18)和更低版本的系统,使用Dalvik虚拟机(VM)。

  • •.在安卓4.4(应用编程接口级别19)中,安卓运行时(Android RunTime (ART))虚拟机(VM)是可选项,而Dalvik虚拟机(VM)是默认选项。

  • •.安卓5.0(应用编程接口级别21)及更高版本中,使用安卓运行时虚拟机(ART VM)。

虚拟机(VM)负责垃圾回收。Dalvik虚拟机(VM)使用标记并清除(mark-and-sweep)模式来进行垃圾回收。安卓运行时虚拟机(ART VM)使用世代(generational)模式,并在需要更彻底进行垃圾回收时使用标记并清除(mark-and-sweep)模式,比如,在内存已经严重碎片化的情况下就会使用后者。logcat Monitor会显示一些消息,表明当时发生的垃圾回收类型以及原因。

Memory Monitor的结果,在不同的虚拟机(VM)中会有差异。所以,如果妳想同时支持两种虚拟机的话,妳就应当对两种虚拟机都进行测试。另外,不同的应用编程接口级别中的虚拟机,其行为也可能不同。例如,安卓2.3(应用编程接口级别10)及更低版本系统中的Dalvik 虚拟机,会使用外部分配的内存,而更高版本的系统呢,只会在Dalvik 堆中分配内存。

妳不能通过对Dalvik 和ART 虚拟机进行配置来调整性能。正确的做法是,检查妳自己的代码,找到方法,改进它的运作模式,例如,减少巨大的数组的大小。

可以通过代码来影响到虚拟机进行垃圾回收的时间,当然,这并不是一种好的做法。这些技巧,是与虚拟机严重相关的。欲知更多信息,则阅读 定位 到垃圾回收 (GC) 中的问题 监视内存使用情况

ART虚拟机,相比于Dalvik 虚拟机,提升了性能、开发效率和调试效率。欲知更多信息,则阅读 ART Dalvik

在Memory Monitor中显示出某个正在运行的应用

要想在Memory Monitor 中显示出某个设备或模拟器中运行的应用,则做以下步骤:

  1. 1. 满足 基本 要求和依赖项

  2. 2.打开一个应用项目。

  3. 3. 在某个硬件设备或模拟器中 运行 该应用

  4. 4. 显示Android Monitor

  5. 5. 点击 Monitors 标签页, 显示 Memory Monitor

  6. 6.点击下图所示的Pause 按钮,取消选中状态,以启用Memory Monitor。

  1. 图中的y轴显示的是可用及已分配的内存数量,以兆字节(megabytes)为单位。x轴显示的是已逝去的时间;开始是若干秒,然后是若干分钟和若干秒,如此下去。内存数量以兆字节为单位,可用内存,以一种较淡的颜色来表示,已分配的内存,以一种较深的颜色来表示。每当已分配的内存中出现了一次税利的下跌,就表示发生了一次垃圾回收事件。

    要想强制产生一次垃圾回收事件,则点击Initiate GC 按钮,如下图所示。

  1. 在下图中,虚拟机发动了第一次垃圾回收事件,而开发者强制发动了第二次。

  2. 7.与妳的应用进行交互,并且在Memory Monitor 中观察,交互过程是如何影响到内存使用情况的。妳可以了解到妳的应用程序的垃圾回收模式,以判断,它是否处于健康状态,是否符合妳的预期。

    这个图表能够向妳展示出潜在的问题:

    • •.过量的垃圾回收事件,会降低应用程序的运行速度。

    • •.应用程序内存用尽,导致程序崩溃。

    • •.潜在的内存泄露。

    例如,妳可能观察到以下迹象:

    • •.妳的应用程序是静态的,但是,从监视器中,观看到了内存持续被分配。

    • •.妳在监视器中观察到了内存分配产生的尖锐脉冲(spikes),但是妳并不认为应用程序中有任何逻辑会引起这种行为。

  1. 1. 要停止Memory Monitor,则再次点击Pause 按钮,以选中它,如下图所示。

强制发动一次垃圾回收事件

一般情况下,虚拟机只会在绝对必要的情况下才进行垃圾回收,因为这个动作狠昂贵。然而,在特定情况下,强制进行垃圾回收是有用处的。例如,在定位内存泄露的过程中,如果妳想确定某个巨大对象是否已经被成功释放,那么,可以更频繁地发动垃圾回收。

要想强制发动一次垃圾回收事件,则:

对Java 堆和内存分配情况进行快照

在Memory Monitor 处于运行状态或者暂停状态的情况下,可进行快照:

未知美人

未知美人

未知美人

Your opinions
Your name:Email:Website url:Opinion content:
- no title specified

HxLauncher: Launch Android applications by voice commands