【Android性能优化】内存优化前置知识剖析

文章目录

  • 前言
  • 内存核心指标
    • VSS(Virtual Set Size)
    • RSS(Resident Set Size )
    • PSS(Proportional Set Size)
      • VSS和RSS的区别
    • USS (Unique Set Size)
  • adb shell
    • adb shell getprop ro.product.model
    • adb shell dumpsys battery
    • adb shell wm size
    • adb shell wm density
    • adb shell dumpsys window displays
    • adb shell cat /proc/cpuinfo
  • 内存分析命令
    • cat /system/build.prop
    • dumpsys meminfo:
  • vmstat:
    • vmstat相关简写解析
      • procs(进程)
      • memory(内存)
      • system(系统)
      • cpu(处理器)
  • 本地检测
    • top命令
    • 把top日志输出到文件
  • Java内存分配和垃圾回收算法
  • Android kill机制

前言

内存优化作为Android性能优化中非常重要的一环,这篇blog主要记录了跟内存优化相关的重要命令、核心指标、相关原理的解析。作为前置知识,起到奠基的作用。阅读完本篇内容,你将对于Android的内存优化有个大致的知识框架。更加详细的解析,会在后续blog中更新。

内存核心指标

Android有一个名为procrank(/system/xbin/procrank)的工具,它按照从最高到最低的顺序列出Linux进程的内存使用情况。报告的大小包括VSS、RSS、PSS和USS等。
为了简化描述,内存将以页面而不是字节的形式表示。我们的Linux系统在最低级别以4096字节的页面管理内存。

VSS(Virtual Set Size)

虚拟耗用的内存(包含与其他进程共享占用的虚拟内存)。

VSS是进程的总可访问地址空间。该大小还包括可能尚未写入的内存,例如已分配但尚未写入的malloc。VSS对于确定进程的真实内存使用几乎没有用处。

RSS(Resident Set Size )

实际使用的物理内存(包含与其他进程共享占用的内存)

RSS表示一个进程在RAM中实际拥有的总内存。RSS可能具有误导性,因为它包括了该进程与其他进程共享的实际物理内存使用量,例如,对于共享库,其往往只加载到内存中一次,而不管有多少进程使用它。RSS不能准确地表示单个进程的内存使用情况。

PSS(Proportional Set Size)

实际使用的物理内存(按比例包含与其他进程共享占用的内存)

PSS与RSS不同之处是,对于进程间共享的内存,其按比例报告其所使用的共享物理内存大小。

比如有n进程同时在使用一个共享,那对于单个进程其占用的该共享库的内存为1/n。如果三个进程都使用一个有30页的享库,那么这个库将只向每个进程报告的PSS贡献10页。

PSS是一个非常有用的数字,因为当系统中所有进程的PSS加在一起时,就可以很好地表示系统中总的内存使用量。当一个进程被终止时,贡献给它的PSS的共享库将按比例分配给仍然使用该库的其他进程的PSS总数。这样,PSS可能有点误导人,因为当进程被终止时,PSS不能准确地表示返回到整个系统的内存。

VSS和RSS的区别

PSS与RSS不同之处在于,它报告了其共享库的比例大小。例如,如果三个进程都使用一个有30页的共享库,那么该库将只为每个进程报告的PSS贡献10页。

USS (Unique Set Size)

进程独自占用的物理内存(不包含与其他进程共享占用的内存)

USS表示进程占用的总的物理的存大小,也就是说这部分内存是该进程完全独占的。USS是一个非常有用的数字,因为它表示运行特定进程的实际增量成本。当进程被终止时,USS是实际返回给条统的总内存。

当最初怀疑某个进程存在内存泄漏时,USS是最好的监视数字。

Python有个很好的工具叫做smem,它可以输出包括所有这些类别的内存统计信息。

对于单个进程,一般来说内存占用大小排序如下:VSS>=RSS>=PSS >= USS

adb shell

adb shell getprop ro.product.model

获取设备型号

adb shell dumpsys battery

获取设备电池信息

Current Battery Service state:
  AC powered: false
  USB powered: true
  Wireless powered: false
  Max charging current: 0
  Max charging voltage: 0
  Charge counter: 4120000
  status: 4
  health: 2
  present: true
  level: 80
  scale: 100
  voltage: 3978
  temperature: 380
  technology: Li-ion

adb shell wm size

物理屏幕分辨率

Physical size: 600x1024

adb shell wm density

屏幕像素密度

Physical density: 240

adb shell dumpsys window displays

日志太长,影响篇幅,就不贴上来了。这个命令总体可以提供的信息有:

  • 屏幕分辨率和密度。
  • 显示的屏幕方向。
  • 系统中所有窗口的状态,包括它们的标识符、大小、位置等。
  • 当前活动窗口和焦点窗口的信息。
  • 显示器的物理尺寸和显示密度。
  • 前台应用程序的详细信息。

adb shell cat /proc/cpuinfo

提供cpu的信息

参考:https://developer.android.com/tools/adb?hl=zh-cn

内存分析命令

cat /system/build.prop

这个命令,我在实际运行的时候,被拒绝了。也许是需要root权限。

它能提供的信息:
设备的型号和制造商。
Android 系统的版本号。
系统的构建日期和时间戳。
系统的一些配置参数,比如默认语言、地区、时区等。
硬件配置信息,如屏幕密度、处理器架构、内存大小等。

dumpsys meminfo:

这个命令用于在Android系统中获取内存信息。它提供了有关系统中内存使用情况的详细信息,包括各个进程的内存使用情况、缓存和缓冲区的使用情况等。通过分析这些信息,可以了解系统中内存的分配情况,以及可能存在的内存泄漏或性能问题。

Q10A:/ $ dumpsys meminfo
Applications Memory Usage (in Kilobytes):
Uptime: 126311204 Realtime: 126311204

Total PSS by process:
     80,347K: system (pid 2353)
     51,351K: com.android.systemui (pid 2606 / activities)
     39,563K: com.pax.usbcommdemo (pid 3989 / activities)
     34,159K: com.pax.security (pid 5104 / activities)
     31,535K: com.android.launcher3 (pid 2887 / activities)
     25,687K: com.android.settings (pid 2723)
     23,025K: zygote (pid 2054)
     22,616K: com.pax.daemon (pid 3118)
     15,588K: surfaceflinger (pid 2081)
     13,907K: com.android.inputmethod.latin (pid 2847)
     10,608K: android.process.media (pid 3261)
     10,300K: media.swcodec (pid 2147)
      9,541K: com.paxdroid.osmanager (pid 3139)
      9,423K: com.android.permissioncontroller (pid 3741)
      9,037K: com.android.traceur (pid 3777)
      8,934K: audioserver (pid 2078)
      8,749K: com.pax.ipp.neptune (pid 3652)
      8,362K: com.paxdroid.verify (pid 2789)
      8,357K: com.android.managedprovisioning (pid 3673)
      8,178K: mediaserver (pid 2136)
      7,869K: com.pax.rki (pid 3310)
      7,479K: com.android.keychain (pid 3375)
      7,309K: com.android.packageinstaller (pid 3719)
      7,303K: media.codec (pid 2140)
      6,829K: android.ext.services (pid 2815)
      6,685K: com.android.se (pid 3164)
      6,026K: media.extractor (pid 2134)
      5,567K: [email protected] (pid 2059)
      4,420K: cameraserver (pid 2125)
      3,791K: rild (pid 2146)
      3,356K: logd (pid 1878)
      3,245K: netd (pid 2055)
      2,723K: adbd (pid 3107)
      2,719K: init (pid 1)
      2,467K: [email protected] (pid 2590)
      2,382K: [email protected] (pid 2064)
      2,210K: apexd (pid 2033)
      2,208K: paxservice (pid 2120)
      2,110K: media.metrics (pid 2135)
      1,983K: drmserver (pid 2126)
      1,886K: vold (pid 1883)
      1,804K: systool_server (pid 2121)
      1,722K: ueventd (pid 1463)
      1,699K: init (pid 1460)
      1,658K: keystore (pid 2130)
      1,615K: statsd (pid 2137)
      1,500K: idmap2d (pid 2127)
      1,490K: [email protected] (pid 1970)
      1,483K: [email protected] (pid 2063)
      1,418K: init (pid 1461)
      1,404K: [email protected] (pid 2058)
      1,321K: installd (pid 2129)
      1,213K: auth_bpadownload (pid 3252)
      1,150K: [email protected] (pid 2069)
      1,143K: mediadrmserver (pid 2131)
      1,076K: storaged (pid 2138)
      1,055K: gatekeeperd (pid 2148)
      1,036K: gpuservice (pid 2079)
      1,031K: crda.uevent (pid 2143)
      1,015K: hwservicemanager (pid 1880)
      1,014K: [email protected] (pid 2070)
        971K: [email protected] (pid 2061)
        950K: wificond (pid 2139)
        940K: incidentd (pid 2128)
        863K: [email protected] (pid 2065)
        843K: displayservice (pid 3047)
        830K: [email protected] (pid 2060)
        822K: [email protected] (pid 2068)
        811K: [email protected] (pid 2062)
        806K: abb (pid 3503)
        800K: [email protected] (pid 2067)
        795K: [email protected] (pid 2066)
        794K: [email protected] (pid 1969)
        786K: [email protected] (pid 2071)
        770K: vndservicemanager (pid 1881)
        715K: sleep (pid 11628)
        665K: servicemanager (pid 1879)
        647K: ip6tables-restore (pid 2166)
        635K: iptables-restore (pid 2165)
        594K: [email protected] (pid 2057)
        589K: dumpsys (pid 11621)
        587K: ashmemd (pid 2077)
        575K: tee_supplicant (pid 1971)
        553K: radio_monitor (pid 2145)
        543K: process-tracker (pid 20256)
        540K: process-tracker (pid 19356)
        539K: process-tracker (pid 21727)
        532K: pax_logcat (pid 2132)
        529K: sh (pid 11604)
        521K: sh (pid 1905)
        518K: dom2reg (pid 2144)
        518K: sh (pid 3044)
        508K: lmkd (pid 2080)
        494K: tombstoned (pid 2149)
        417K: paxdroid_logservice (pid 2122)

Total PSS by OOM adjustment:
    170,268K: Native
         23,025K: zygote (pid 2054)
         15,588K: surfaceflinger (pid 2081)
         10,300K: media.swcodec (pid 2147)
          8,934K: audioserver (pid 2078)
          8,178K: mediaserver (pid 2136)
          7,303K: media.codec (pid 2140)
          6,026K: media.extractor (pid 2134)
          5,567K: [email protected] (pid 2059)
          4,420K: cameraserver (pid 2125)
          3,791K: rild (pid 2146)
          3,356K: logd (pid 1878)
          3,245K: netd (pid 2055)
          2,723K: adbd (pid 3107)
          2,719K: init (pid 1)
          2,467K: [email protected] (pid 2590)
          2,382K: [email protected] (pid 2064)
          2,210K: apexd (pid 2033)
          2,208K: paxservice (pid 2120)
          2,110K: media.metrics (pid 2135)
          1,983K: drmserver (pid 2126)
          1,886K: vold (pid 1883)
          1,804K: systool_server (pid 2121)
          1,722K: ueventd (pid 1463)
          1,699K: init (pid 1460)
          1,658K: keystore (pid 2130)
          1,615K: statsd (pid 2137)
          1,500K: idmap2d (pid 2127)
          1,490K: [email protected] (pid 1970)
          1,483K: [email protected] (pid 2063)
          1,418K: init (pid 1461)
          1,404K: [email protected] (pid 2058)
          1,321K: installd (pid 2129)
          1,213K: auth_bpadownload (pid 3252)
          1,150K: [email protected] (pid 2069)
          1,143K: mediadrmserver (pid 2131)
          1,076K: storaged (pid 2138)
          1,055K: gatekeeperd (pid 2148)
          1,036K: gpuservice (pid 2079)
          1,031K: crda.uevent (pid 2143)
          1,015K: hwservicemanager (pid 1880)
          1,014K: [email protected] (pid 2070)
            971K: [email protected] (pid 2061)
            950K: wificond (pid 2139)
            940K: incidentd (pid 2128)
            863K: [email protected] (pid 2065)
            843K: displayservice (pid 3047)
            830K: [email protected] (pid 2060)
            822K: [email protected] (pid 2068)
            811K: [email protected] (pid 2062)
            806K: abb (pid 3503)
            800K: [email protected] (pid 2067)
            795K: [email protected] (pid 2066)
            794K: [email protected] (pid 1969)
            786K: [email protected] (pid 2071)
            770K: vndservicemanager (pid 1881)
            715K: sleep (pid 11628)
            665K: servicemanager (pid 1879)
            647K: ip6tables-restore (pid 2166)
            635K: iptables-restore (pid 2165)
            594K: [email protected] (pid 2057)
            589K: dumpsys (pid 11621)
            587K: ashmemd (pid 2077)
            575K: tee_supplicant (pid 1971)
            553K: radio_monitor (pid 2145)
            543K: process-tracker (pid 20256)
            540K: process-tracker (pid 19356)
            539K: process-tracker (pid 21727)
            532K: pax_logcat (pid 2132)
            529K: sh (pid 11604)
            521K: sh (pid 1905)
            518K: dom2reg (pid 2144)
            518K: sh (pid 3044)
            508K: lmkd (pid 2080)
            494K: tombstoned (pid 2149)
            417K: paxdroid_logservice (pid 2122)
     80,347K: System
         80,347K: system (pid 2353)
    124,242K: Persistent
         51,351K: com.android.systemui (pid 2606 / activities)
         25,687K: com.android.settings (pid 2723)
         22,616K: com.pax.daemon (pid 3118)
          9,541K: com.paxdroid.osmanager (pid 3139)
          8,362K: com.paxdroid.verify (pid 2789)
          6,685K: com.android.se (pid 3164)
     34,159K: Foreground
         34,159K: com.pax.security (pid 5104 / activities)
     31,535K: Visible
         31,535K: com.android.launcher3 (pid 2887 / activities)
     21,776K: Perceptible
         13,907K: com.android.inputmethod.latin (pid 2847)
          7,869K: com.pax.rki (pid 3310)
     39,563K: Previous
         39,563K: com.pax.usbcommdemo (pid 3989 / activities)
     67,791K: Cached
         10,608K: android.process.media (pid 3261)
          9,423K: com.android.permissioncontroller (pid 3741)
          9,037K: com.android.traceur (pid 3777)
          8,749K: com.pax.ipp.neptune (pid 3652)
          8,357K: com.android.managedprovisioning (pid 3673)
          7,479K: com.android.keychain (pid 3375)
          7,309K: com.android.packageinstaller (pid 3719)
          6,829K: android.ext.services (pid 2815)

Total PSS by category:
    123,861K: .so mmap
     65,970K: Native
     63,937K: .apk mmap
     58,407K: GL mtrack
     45,736K: Dalvik
     39,339K: .art mmap
     35,034K: .dex mmap
     32,557K: Unknown
     31,852K: .jar mmap
     20,447K: Other mmap
     14,430K: .oat mmap
     10,452K: Dalvik Other
      9,684K: .ttf mmap
      4,376K: EGL mtrack
      3,008K: Stack
        743K: Other dev
        736K: Ashmem
          0K: Cursor
          0K: Gfx dev
          0K: Other mtrack

Total RAM:   994,652K (status normal)
 Free RAM:   355,931K (   67,791K cached pss +   217,700K cached kernel +    70,440K free)
 Used RAM:   618,246K (  501,890K used pss +   116,356K kernel)
 Lost RAM:    27,227K
     ZRAM:     2,360K physical used for     9,140K in swap (  745,984K total swap)
   Tuning: 128 (large 256), oom   184,320K, restore limit    61,440K (low-ram)

vmstat:

这个命令用于在Linux系统中显示虚拟内存统计信息。它提供了有关系统内存使用情况的实时数据,包括活动和非活动内存、缓存和缓冲区、交换分区等。vmstat命令可以帮助识别系统中的内存瓶颈,并监视系统内存的使用情况。

vmstat相关简写解析

procs(进程)

r:Running队列中进程数量
b:I0 wait的进程数量

memory(内存)

free:可用内存大小
mapped:mmap映射的内存大小
anon:匿名内存大小
slab:slab的内存大小

system(系统)

in:每秒的中断次数(包括时钟中断)
cs:每秒上下文切换的次数

cpu(处理器)

us:user time
ni: nice time
sy:system time
id: idle time
wa:iowait time
ir: interrupt time

本地检测

top命令

进入shell后,输入top,输出以下日志:
关于mem、swap、buffers、cached等参数涉及到Linux系统原理,后续会出文章来说明。
【Android性能优化】内存优化前置知识剖析_第1张图片

把top日志输出到文件

该命令需要root权限

adb shell top -d 20 > meminfo

这个命令是使用adb命令连接到Android设备的shell,并且运行了一个名为top的命令,其参数-d 20表示每隔20秒更新一次,并将输出重定向到名为meminfo的文件中。

  • adb shell: 这部分启动了adb工具,并连接到设备的shell。
  • top -d 20: 这部分运行了top命令,该命令用于显示当前运行的进程和它们的资源占用情况。参数-d 20表示每20秒更新一次显示。
  • >meminfo: 这部分将top命令的输出重定向到名为meminfo的文件中,而不是在终端窗口中显示输出。

用Python把内存信息打印到文件里面的脚本。

Java内存分配和垃圾回收算法

标记-清除算法:

  • 理论上,先对标记的对象进行清理。
  • 优点:可以清除不再需要的对象,解决了内存泄漏问题。
  • 缺点:效率不高,会产生大量碎片。

复制算法:

  • 将存活对象全部拷贝到另一半空间,然后清理另一半空间。
  • 优点:内存空间连续,算法高效。
  • 缺点:会浪费一半空间。

标记-整理算法:

  • 将存活对象往一端移动,清理其余部分。
  • 优点:避免了内存碎片。
  • 缺点:标记过程与“标记-清除”相同,可能产生空间浪费。

分代收集算法:

  • 结合多种收集算法优势。
  • 新生代对象使用复制算法,老年代对象使用标记-整理算法。
  • 新生代对象存活率低,老年代对象存活率高。

Android kill机制

在Android的lowmemroy kíller机制中,会对于所有进程进行分类,对于每一类别的进程会有其oom_adj值的取值范围,oom_adj值越高则代表进程越不重要,在系统执行低杀操作时,会从oom_adj值越高的开始杀。

对于期望较长时间留在后台的服务,应该将服务运行在单独的进程里,即是UI进程与Servie进程分离,这样期望长时间留在后台的Serivce会存在与一个被lowmemory killer分类为Service 进程的服务而获得较小的Adj值,而占有大量内存的UI进程则会分类为Cached进程,能够在需要的时候更快地被回收。
【Android性能优化】内存优化前置知识剖析_第2张图片

图片来源:https://gityuan.com/2018/05/19/android-process-adj/ 侵删

你可能感兴趣的:(#,Android性能优化,android,性能优化)