如何分析Android APP 内存大小

Because Android is designed for mobile devices, you should always be careful about how much random-access memory (RAM) your app uses. Although Android’s Dalvik virtual machine performs routine garbage collection, this doesn’t mean you can ignore when and where your app allocates and releases memory. In order to provide a stable user experience that allows the system to quickly switch between apps, it’s important that your app does not needlessly consume memory when the user is not interacting with it.

由于Android是专为移动设备,你一定要加倍小心APP内存大小。虽然Android的Dalvik虚拟机执行日常垃圾收集,这并不意味着你可以忽略什么时候或者在哪里分配释放内存。为了提供一个稳定的用户体验,使系统应用程序之间快速切换,当用户不与它进行交互,你的应用程序不必要的消耗内存。

The simplest place to begin investigating your apps memory usage is the Dalvik log messages. You'll find these log messages in logcat (the output is available in the Device Monitor or directly in IDEs such as Eclipse and Android Studio).

开始调查你的应用程序的内存使用最简单的地方是Dalvik的日志信息。你会发现在logcat的这些日志信息(输出设备监视器或直接在集成开发环境如Eclipse和Android Studio)

Every time a garbage collection occurs, logcat prints a message with the following information:

垃圾收集发生时,都会logcat的打印以下信息的消息:

D/dalvikvm: <GC_Reason> <Amount_freed>, <Heap_stats>, <External_memory_stats>, <Pause_time>
GC Reason
What triggered the garbage collection and what kind of collection it is. Reasons that may appear include:
GC_CONCURRENT

A concurrent garbage collection that frees up memory as your heap begins to fill up.

当堆填充时并发垃圾回收内存。

GC_FOR_MALLOC

A garbage collection caused because your app attempted to allocate memory when your heap was already full, so the system had to stop your app and reclaim memory.

垃圾回收造成的,因为你的应用程序尝试分配内存时,你堆已经满了,所以系统必须停止你的应用程序和回收内存。

GC_HPROF_DUMP_HEAP

A garbage collection that occurs when you create an HPROF file to analyze your heap.

当你创建一个HPROF文件堆发生垃圾回收。

GC_EXPLICIT

An explicit garbage collection, such as when you call gc() (which you should avoid calling and instead trust the garbage collector to run when needed).

明确垃圾收集,当你调用GC(你应该避免调用,而是信任的垃圾收集器在需要时运行)等。

GC_EXTERNAL_ALLOC

This happens only on API level 10 and lower (newer versions allocate everything in the Dalvik heap). A garbage collection for externally allocated memory (such as the pixel data stored in native memory or NIO byte buffers).

Android 2.2之后的版本不在使用。当为位图垃圾回收资源时。

Amount freed

The amount of memory reclaimed from this garbage collection.

从垃圾回收中获得内存大小。  

Heap stats

Percentage free and (number of live objects)/(total heap size).

剩余(活动对象的数量) / (总堆大小)

External memory stats

Externally allocated memory on API level 10 and lower (amount of allocated memory) / (limit at which collection will occur).

Android 2.2之后的版本不在使用

Pause time
Larger heaps will have larger pause times. Concurrent pause times show two pauses: one at the beginning of the collection and another near the end.

For example:

D/dalvikvm( 9050): GC_CONCURRENT freed 2049K, 65% free 3571K/9991K, external 4703K/5261K, paused 2ms+2ms

As these log messages stack up, look out for increases in the heap stats (the 3571K/9991K value in the above example). If this value continues to increase and doesn't ever seem to get smaller, you could have a memory leak.

由于这些日志消息叠起来,寻找出增加的堆统计(在上述的例子中3571K / 9991K值)。如果这个值继续增加,不永远似乎变得越来越小,你可以有内存泄漏。

Viewing Overall Memory Allocations


For further analysis, you may want to observe how your app's memory is divided between different types of RAM allocation with the following adb command:

对于进一步的分析,你可能要观察一下你的应用程序的内存是不同类型的内存分配与下面的adb命令之间的划分:

adb shell dumpsys meminfo <package_name>

The output lists all of your app's current allocations, measured in kilobytes.

输出列出了所有你的应用程序的当前分配,计量单位为千字节。

When inspecting this information, you should be familiar with the following types of allocation:

当检查这些信息,你应该熟悉分配以下类型:

Private (Clean and Dirty) RAM

This is memory that is being used by only your process. This is the bulk of the RAM that the system can reclaim when your app’s process is destroyed. Generally, the most important portion of this is “private dirty” RAM, which is the most expensive because it is used by only your process and its contents exist only in RAM so can’t be paged to storage (because Android does not use swap). All Dalvik and native heap allocations you make will be private dirty RAM; Dalvik and native allocations you share with the Zygote process are shared dirty RAM.

这是正在被你的APP使用的内存。当你的APP被破坏了,这是可以被系统回收的很大一部分内存。通常private dirty 是最重要的部分,主要原始是这块内存只被你的进程使用并且不能放到硬盘。所有的Dalvik 和本地堆都是private dirty RAM;Dalvik及本地应用程序与Zygote共享的未shared dirty RAM.

Proportional Set Size (PSS)

This is a measurement of your app’s RAM use that takes into account sharing pages across processes. Any RAM pages that are unique to your process directly contribute to its PSS value, while pages that are shared with other processes contribute to the PSS value only in proportion to the amount of sharing. For example, a page that is shared between two processes will contribute half of its size to the PSS of each process.

这是你的应用程序的内存使用,考虑到整个过程账号的共享页面进行测量。任何进程独有的内存属于PSS,然而与其它进程共享的内存也有一部分属于PSS,例如4K内存被两个进程共享,则有一半属于其中一个进程的PSS。

For example, below is the the output for Gmail’s process on a tablet device. There is a lot of information here, but key points for discussion are listed below.

例如,下面是对Gmail的处理的平板设备上的输出。有大量的信息在这里,但关键点讨论如下所列

Note: The information you see may vary slightly from what is shown here, as some details of the output differ across platform versions.

你看到的信息可能与这里显示,作为输出的一些细节有所不同跨平台的版本略有不同

** MEMINFO in pid 9953 [com.google.android.gm] **
                 Pss     Pss  Shared Private  Shared Private    Heap    Heap    Heap
               Total   Clean   Dirty   Dirty   Clean   Clean    Size   Alloc    Free
              ------  ------  ------  ------  ------  ------  ------  ------  ------
  Native Heap      0       0       0       0       0       0    7800    7637(6)  126
  Dalvik Heap   5110(3)    0    4136    4988(3)    0       0    9168    8958(6)  210
 Dalvik Other   2850       0    2684    2772       0       0
        Stack     36       0       8      36       0       0
       Cursor    136       0       0     136       0       0
       Ashmem     12       0      28       0       0       0
    Other dev    380       0      24     376       0       4
     .so mmap   5443(5) 1996    2584    2664(5) 5788    1996(5)
    .apk mmap    235      32       0       0    1252      32
    .ttf mmap     36      12       0       0      88      12
    .dex mmap   3019(5) 2148       0       0    8936    2148(5)
   Other mmap    107       0       8       8     324      68
      Unknown   6994(4)    0     252    6992(4)    0       0
        TOTAL  24358(1) 4188    9724   17972(2)16388    4260(2)16968   16595     336

 Objects
               Views:    426         ViewRootImpl:        3(8)
         AppContexts:      6(7)        Activities:        2(7)
              Assets:      2        AssetManagers:        2
       Local Binders:     64        Proxy Binders:       34
    Death Recipients:      0
     OpenSSL Sockets:      1

 SQL
         MEMORY_USED:   1739
  PAGECACHE_OVERFLOW:   1164          MALLOC_SIZE:       62

Generally, you should be concerned with only the Pss Total and Private Dirty columns. In some cases, the Private Clean and Heap Alloc columns also offer interesting data. Here is some more information about the different memory allocations (the rows) you should observe:

通常情况下,你应该关心只PSS的总和与Private Dirty。在某些情况下,Private Clean和Heap Alloc列也提供了有趣的数据。下面是关于不同的内存分配更多的信息.

Dalvik Heap

The RAM used by Dalvik allocations in your app. The Pss Total includes all Zygote allocations (weighted by their sharing across processes, as described in the PSS definition above). The Private Dirty number is the actual RAM committed to only your app’s heap, composed of your own allocations and any Zygote allocation pages that have been modified since forking your app’s process from Zygote.

Note: On newer platform versions that have the Dalvik Other section, the Pss Total and Private Dirty numbers for Dalvik Heap do not include Dalvik overhead such as the just-in-time compilation (JIT) and garbage collection (GC) bookkeeping, whereas older versions list it all combined under Dalvik.

The Heap Alloc is the amount of memory that the Dalvik and native heap allocators keep track of for your app. This value is larger than Pss Total and Private Dirty because your process was forked from Zygote and it includes allocations that your process shares with all the others.

Heap Alloc 是Dalvik 和 native heap 内存的综合,但是它的值要比他们大,因它包括共享内存,如Zygote.

.so mmap and  .dex mmap
The RAM being used for mmapped  .so (native) and  .dex (Dalvik) code. The  Pss Total number includes platform code shared across apps; the  Private Clean is your app’s own code. Generally, the actual mapped size will be much larger—the RAM here is only what currently needs to be in RAM for code that has been executed by the app. However, the .so mmap has a large private dirty, which is due to fix-ups to the native code when it was loaded into its final address.
Unknown
Any RAM pages that the system could not classify into one of the other more specific items. Currently, this contains mostly native allocations, which cannot be identified by the tool when collecting this data due to Address Space Layout Randomization (ASLR). As with the Dalvik heap, the  Pss Total for Unknown takes into account sharing with Zygote, and  Private Dirty is unknown RAM dedicated to only your app.
TOTAL
The total Proportional Set Size (PSS) RAM used by your process. This is the sum of all PSS fields above it. It indicates the overall memory weight of your process, which can be directly compared with other processes and the total available RAM.

The Private Dirty and Private Clean are the total allocations within your process, which are not shared with other processes. Together (especially Private Dirty), this is the amount of RAM that will be released back to the system when your process is destroyed. Dirty RAM is pages that have been modified and so must stay committed to RAM (because there is no swap); clean RAM is pages that have been mapped from a persistent file (such as code being executed) and so can be paged out if not used for a while.

ViewRootImpl
The number of root views that are active in your process. Each root view is associated with a window, so this can help you identify memory leaks involving dialogs or other windows.
AppContexts and  Activities
The number of app  Context and  Activity objects that currently live in your process. This can be useful to quickly identify leaked  Activity objects that can’t be garbage collected due to static references on them, which is common. These objects often have a lot of other allocations associated with them and so are a good way to track large memory leaks.

Note: A View or Drawable object also holds a reference to the Activity that it's from, so holding a View or Drawable object can also lead to your app leaking an Activity.


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值