如何分析Android APP 内存大小
2015-02-28 13:43
218 查看
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的打印以下信息的消息:
GC ReasonWhat triggered the garbage collection and what kind of collection it is. Reasons that may appear include:
A concurrent garbage collection that frees up memory as your heap begins to fill up.
当堆填充时并发垃圾回收内存。
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.
垃圾回收造成的,因为你的应用程序尝试分配内存时,你堆已经满了,所以系统必须停止你的应用程序和回收内存。
A garbage collection that occurs when you create an HPROF file to analyze your heap.
当你创建一个HPROF文件堆发生垃圾回收。
An explicit garbage collection, such as when you call
you should avoid calling and instead trust the garbage collector to run when needed).
明确垃圾收集,当你调用GC(你应该避免调用,而是信任的垃圾收集器在需要时运行)等。
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 timeLarger 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:
As these log messages stack up, look out for increases in the heap stats (the
smaller, you could have a memory leak.
由于这些日志消息叠起来,寻找出增加的堆统计(在上述的例子中3571K / 9991K值)。如果这个值继续增加,不永远似乎变得越来越小,你可以有内存泄漏。
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命令之间的划分:
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.
你看到的信息可能与这里显示,作为输出的一些细节有所不同跨平台的版本略有不同
Generally, you should be concerned with only the
通常情况下,你应该关心只PSS的总和与Private Dirty。在某些情况下,Private Clean和Heap Alloc列也提供了有趣的数据。下面是关于不同的内存分配更多的信息.
The RAM used by Dalvik allocations in your app. The
The
app’s process from Zygote.
Note: On newer platform versions that have the
The
Heap Alloc 是Dalvik 和 native heap 内存的综合,但是它的值要比他们大,因它包括共享内存,如Zygote.
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.
Space Layout Randomization (ASLR). As with the Dalvik heap, the
the total available RAM.
The
within your process, which are not shared with other processes. Together (especially
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.
that currently live in your process. This can be useful to quickly identify leaked
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
also holds a reference to the
it's from, so holding a
can also lead to your app leaking an
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 ReasonWhat 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 timeLarger 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/9991Kvalue 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 Totaland
Private Dirtycolumns. In some cases, the
Private Cleanand
Heap Alloccolumns 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 Totalincludes all Zygote allocations (weighted by their sharing across processes, as described in the PSS definition above).
The
Private Dirtynumber 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 Othersection, the
Pss Totaland
Private Dirtynumbers 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 Allocis the amount of memory that the Dalvik and native heap allocators keep track of for your app. This value is larger than
Pss Totaland
Private Dirtybecause 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 mmapand
.dex mmapThe RAM being used for mmapped
.so(native) and
.dex(Dalvik) code. The
Pss Totalnumber includes platform code shared across apps; the
Private Cleanis 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.
UnknownAny 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 Totalfor Unknown takes into account sharing with Zygote, and
Private Dirtyis unknown RAM dedicated to only your app.
TOTALThe 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 Dirtyand
Private Cleanare 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.
ViewRootImplThe 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.
AppContextsand
ActivitiesThe number of app
Contextand
Activityobjects
that currently live in your process. This can be useful to quickly identify leaked
Activityobjects
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
Viewor
Drawableobject
also holds a reference to the
Activitythat
it's from, so holding a
Viewor
Drawableobject
can also lead to your app leaking an
Activity.
相关文章推荐
- Android 如何获取App内存大小
- Java乔晓松-Android SD卡路径问题以及如何获取SDCard内存大小
- Android内存机制分析2——分析APP内存使用情况
- android app 内存分析
- Android中图片大小、drawable文件夹、图片大小对内存占用的影响分析
- 如何获取 Android 设备的CPU核数、时钟频率以及内存大小
- 返回解释Java乔晓松-Android SD卡路径问题以及如何获取SDCard内存大小
- Android内存机制分析下篇:分析APP内存使用情况
- 如何获取 Android 设备的CPU核数、时钟频率以及内存大小
- Android内存机制分析下篇:分析APP内存使用情况
- 关于Android中图片大小、内存占用与drawable文件夹关系的研究与分析
- Android内存机制分析2——分析APP内存使用情况
- Android内存机制分析下篇:分析APP内存使用情况
- android 中如何分析内存泄漏
- 如何设置android app 的字体大小不受系统字体大小改变的影响
- 如何分析Android的内存使用量
- 【转】Android内存机制分析2——分析APP内存使用情况
- Android内存机制分析下篇:分析APP内存使用情况
- Android内存机制分析上篇:了解Android堆和栈 Android内存机制分析下篇:分析APP内存使用情况
- Android内存机制分析下篇:分析APP内存使用情况