Android内存使用情况分析

简介: Android系统的内存由几个不同的内存池中的几个不同的分配器管理

Android系统的内存由几个不同的内存池中的几个不同的分配器管理。

目录:

  1. 系统内存
  2. 进程内存
    2.1 procrank
    2.2 smem tool
  3. Dalvik Heap
  4. 调试Android应用内存占用情况
    4.1 如何调试native进程内存分配情况
    4.2 libc.debug.malloc


系统内存


通过查看 /proc/meminfo,可以检查机器 上的内存视图。

如果使用DDMS,则可以查看机器,系统和不同执行进程使用的内存摘要。单击SysInfo选项卡,然后在窗格左上角的框中选择“Memory Usage”。


6.png

请注意,您可以通过将鼠标悬停在特定的饼图切片上来获取每个过程的数字。 数字以K和百分比显示。


进程内存


您可以通过检查/proc/<pid> / status来查看单个进程的内存使用情况

有关内存使用的详细信息

  • /proc/<pid>/statm
  • /proc/<pid>/maps
  • /proc/<pid>/smaps
    'top'命令将显示VSS和RSS。另请参阅上面的ddms信息。


procrank

procrank将向您显示进程内存利用率的快速摘要。 默认情况下,它显示Vss,Rss,Pss和Uss,并按Vss排序。 但是,您可以控制排序顺序。

procrank源包含在system/extras/procrank中,二进制文件位于android设备上的/system/ xbin中。

  • Vss = virtual set size--虚拟集大小
  • Rss = resident set size--常驻内存大小
  • Pss = proportional set size--比例集大小
  • Uss = unique set size--独占集大小
    通常,您要观看的两个数字是Pss和Uss(Vss和Rss通常毫无价值,因为它们不能准确反映进程对与其他进程共享的页面的使用情况。)对整体内存负载的影响。
  • Uss是进程独有的页面集。 这是当前终止应用程序时将释放的内存量。
  • Pss是与其他进程共享的内存量,其计算方式是在共享它的进程之间平均分配额度。 这是在进程终止时不会释放的内存,但表示此进程“贡献”的数量
    您还可以使用procrank查看每个进程的工作集大小,并重置工作集大小计数器。
    这是procrank的用法:

# procrank -h
Usage: procrank [ -W ] [ -v | -r | -p | -u | -h ]
    -v  Sort by VSS.
    -r  Sort by RSS.
    -p  Sort by PSS.
    -u  Sort by USS.
        (Default sort order is PSS.)
    -R  Reverse sort order (default is descending).
    -w  Display statistics for working set only.
    -W  Reset working set of all processes.
    -h  Display this help screen.

以下是一些示例输出:

# procrank
  PID      Vss      Rss      Pss      Uss  cmdline
 1217   36848K   35648K   17983K   13956K  system_server
 1276   32200K   32200K   14048K   10116K  android.process.acore
 1189   26920K   26920K    9293K    5500K  zygote
 1321   20328K   20328K    4743K    2344K  android.process.media
 1356   20360K   20360K    4621K    2148K  com.android.email
 1303   20184K   20184K    4381K    1724K  com.android.settings
 1271   19888K   19888K    4297K    1764K  com.android.inputmethod.latin
 1332   19560K   19560K    3993K    1620K  com.android.alarmclock
 1187    5068K    5068K    2119K    1476K  /system/bin/mediaserver
 1384     436K     436K     248K     236K  procrank
    1     212K     212K     200K     200K  /init
  753     572K     572K     171K     136K  /system/bin/rild
  748     340K     340K     163K     152K  /system/bin/sh
  751     388K     388K     156K     140K  /system/bin/vold
 1215     148K     148K     136K     136K  /sbin/adbd
  757     352K     352K     117K      92K  /system/bin/dbus-daemon
  760     404K     404K     104K      80K  /system/bin/keystore
  759     312K     312K     102K      88K  /system/bin/installd
  749     288K     288K      96K      84K  /system/bin/servicemanager
  752     244K     244K      71K      60K  /system/bin/debuggerd

在此示例中,它显示本机守护程序和普通程序比基于Dalvik的服务和程序小一个数量级。 此外,即使是最小的Dalvik程序也需要大约1.5兆(Uss)才能运行。


smem tool

您可以通过smem查看非常详细的每个进程或系统范围的内存信息。安卓smem用法


Dalvik Heap


Dalvik堆由zygote预加载类和数据(从Android 2.2版开始加载超过1900个类)。当zygote分支启动Android应用程序时,新应用程序将获得此堆的写入时拷贝映射,这有助于减少内存和应用程序启动时间。

像许多其他语言的虚拟机一样,Dalvik在堆上进行垃圾收集。 每个VM进程中似乎都有一个单独的线程(称为HeapWorker),用于执行垃圾回收操作。

Dan Borstein谈到堆共享:

它在Android中用于分摊与所有活动VM进程中的公共库类相关联的大量有效只读数据(技术上可写但很少实际编写)的RAM占用空间。 系统在启动时预加载1000多个类,每个类至少消耗一小堆自身,包括经常指向其他对象的宿。 由预加载过程创建的堆与每个生成的VM进程共享写入时拷贝(但实际上并没有写得太多)。 这为每个进程节省了数百KB的"脏"的不可分页RAM,并且还有助于加速进程启动。

请参阅Dianne Hackborn的精彩文章调试Android应用程序内存使用情况


如何调试native进程内存分配情况

setprop dalvik.vm.checkjni true
setprop libc.debug.malloc 10   
setprop setprop dalvik.vm.jniopts forcecopy
start
stop


libc.debug.malloc

系统中的C库(仿生)支持在系统运行时使用malloc代码的不同调试版本的能力。

如果系统属性libc.debug.malloc的值不是0,那么在实例化进程时,C库将使用函数为该进程分配和释放内存。

(请注意,还有其他方法可以使用调试共享库malloc代码。也就是说,如果您在模拟器中运行,并且系统属性ro.kernel.memcheck的值不是'0', 然后你得到20的调试级别。注意,调试级别20只能在模拟器中使用。)

默认情况下,使用标准的malloc / free / calloc / realloc / memalign例程。 通过设置libc.debug.malloc,可以使用不同的例程来检查某些类型的内存错误(例如泄漏和溢出)。 这是通过使用这些不同的例程加载单独的共享库(.so)来完成的。

共享库的名称为:/system/lib/libc_malloc_debug_leak.so和/system/lib/libc_malloc_debug_qemu.so

(通过查看<android-source-root> /bionic/libc/bionic/malloc_debug_common.c获得信息)

libc.debug.malloc(调试级别值)支持的值为:

  • 1 - 执行泄漏检测
  • 5 - 填充分配的内存以检测溢出
  • 10 - 填充内存并添加标记以检测溢出
  • 20 - 为模拟器使用特殊的检测malloc / free例程
    但我不确定这些共享库是否在生产设备中提供。
目录
相关文章
|
15天前
|
Web App开发 监控 JavaScript
监控和分析 JavaScript 内存使用情况
【10月更文挑战第30天】通过使用上述的浏览器开发者工具、性能分析工具和内存泄漏检测工具,可以有效地监控和分析JavaScript内存使用情况,及时发现和解决内存泄漏、过度内存消耗等问题,从而提高JavaScript应用程序的性能和稳定性。在实际开发中,可以根据具体的需求和场景选择合适的工具和方法来进行内存监控和分析。
|
15天前
|
安全 Android开发 数据安全/隐私保护
深入探讨iOS与Android系统安全性对比分析
在移动操作系统领域,iOS和Android无疑是两大巨头。本文从技术角度出发,对这两个系统的架构、安全机制以及用户隐私保护等方面进行了详细的比较分析。通过深入探讨,我们旨在揭示两个系统在安全性方面的差异,并为用户提供一些实用的安全建议。
|
1月前
|
编译器 C语言
动态内存分配与管理详解(附加笔试题分析)(上)
动态内存分配与管理详解(附加笔试题分析)
49 1
|
1月前
|
存储 前端开发 Java
Android MVVM架构模式下如何避免内存泄漏
Android采用MVVM架构开发项目,如何避免内存泄漏风险?怎样避免内存泄漏?
91 1
|
2月前
|
程序员 编译器 C++
【C++核心】C++内存分区模型分析
这篇文章详细解释了C++程序执行时内存的四个区域:代码区、全局区、栈区和堆区,以及如何在这些区域中分配和释放内存。
52 2
|
24天前
|
缓存 Java Shell
Android 系统缓存扫描与清理方法分析
Android 系统缓存从原理探索到实现。
46 15
Android 系统缓存扫描与清理方法分析
|
10天前
|
开发框架 监控 .NET
【Azure App Service】部署在App Service上的.NET应用内存消耗不能超过2GB的情况分析
x64 dotnet runtime is not installed on the app service by default. Since we had the app service running in x64, it was proxying the request to a 32 bit dotnet process which was throwing an OutOfMemoryException with requests >100MB. It worked on the IaaS servers because we had the x64 runtime install
|
11天前
|
Android开发 开发者
Android性能优化——内存管理的艺术
Android性能优化——内存管理的艺术
|
20天前
|
Web App开发 JavaScript 前端开发
使用 Chrome 浏览器的内存分析工具来检测 JavaScript 中的内存泄漏
【10月更文挑战第25天】利用 Chrome 浏览器的内存分析工具,可以较为准确地检测 JavaScript 中的内存泄漏问题,并帮助我们找出潜在的泄漏点,以便采取相应的解决措施。
132 9
|
24天前
|
并行计算 算法 IDE
【灵码助力Cuda算法分析】分析共享内存的矩阵乘法优化
本文介绍了如何利用通义灵码在Visual Studio 2022中对基于CUDA的共享内存矩阵乘法优化代码进行深入分析。文章从整体程序结构入手,逐步深入到线程调度、矩阵分块、循环展开等关键细节,最后通过带入具体值的方式进一步解析复杂循环逻辑,展示了通义灵码在辅助理解和优化CUDA编程中的强大功能。