一、内存相关
参考Android内存分析命令_dumpsys meminfo 算出rss-CSDN博客
1、基本概念
1)PSS & RSS & USS & VSS
a、PSS
- 概念:全称Proportional Set Size,根据进程实际使用的内存量按照共享比例分配给进程的一种内存度量方式。如果多个进程共享同一块内存页,那么共享的内存会被均摊到各个进程的 Pss 中,以更准确地反映各个进程实际使用的内存。
- 意义:根据共享比例分配内存的方式,因此相比于简单的内存统计,它提供了更精确的内存使用情况,避免重复计算共享内存,更好地反映进程真实的内存占用情况。
b、RSS
- 概念:全称Resident Set Size,指示一个进程当前在物理内存中占用的实际大小,包括私有页和共享页的总和。这表示了一个进程实际占用了多少物理内存资源。
- 意义:更加直接地表示了一个进程当前占用的物理内存大小,包括私有页和共享页。通过监控 Rss,可以了解一个进程实际消耗的系统资源,帮助识别内存泄漏、优化内存使用等问题。
2)Dirty & Clean & SwapPss
a、Private Dirty
- 概念:表示进程私有页中已经修改(脏数据)的内存量。这些数据是进程独占并且已被修改的,通常表示进程对这部分内存执行了写入操作
- 意义:Private Dirty占比过高,可能意味着进程频繁地修改内存数据,导致系统产生大量的脏页,增加了写入操作的开销。优化这部分内存的管理,减少不必要的写入操作,可以提高系统性能
b、Private Clean
- 概念:表示进程私有页中未被修改(干净数据)的内存量。这些数据是进程独占但未被修改的,通常表示这部分内存没有发生写入操作。
- 意义:Private Clean 有助于了解进程对内存的读取操作情况和内存使用效率。较高的 Private Clean 可能暗示着进程大量读取数据但很少进行写入操作,即访问模式偏向读取而不是写入。
c、SwapPss Dirty
- 概念:用于监视系统中内存交换操作的情况。当系统内存不足时,操作系统会将部分内存页交换到磁盘的交换空间以腾出物理内存供其他程序使用。
- 意义:SwapPss 提供了一个指标,用于监视系统中内存交换操作的情况。当系统内存不足时,操作系统会将部分内存页交换到磁盘的交换空间以腾出物理内存供其他程序使用。高 SwapPss 值通常暗示着系统内存不足,导致操作系统频繁地将内存页交换到磁盘上的交换空间,这可能会对系统性能产生负面影响。
- 作用:此值通常出现在dumpsys meminfo packagename命令里面
3)Swap & buffers & cache
a、Swap
- 概念:是一种操作系统用来缓解物理内存不足的机制。当系统的物理内存达到极限,而仍有进程需要更多内存时,操作系统会将不常用的内存页面移动到硬盘上的交换空间(Swap),以释放物理内存给那些需要更多内存的进程使用。交换空间通常位于硬盘上,并作为虚拟内存来扩展系统的内存容量。尽管交换空间能够帮助系统继续正常运行,但由于硬盘访问速度远慢于内存,因此使用交换空间会导致系统性能下降。因此,最好的情况是尽量避免频繁地使用交换空间,以确保系统能够在物理内存中运行。
- 作用:Swap实际上是一段占用在磁盘上的空间,他的主要用途如下:在物理内存RAM不足的时候操作系统将一些不常用的内存页从物理RAM移动到SWAP空间里面,这样将腾出更多的RAM空间运行其他活跃的进程;可以通过SWAP作为虚拟内存来扩展系统的内存容量,例如一些手机厂商定制的内存融合方案。
- 意义:如果swap的使用率比较高,说明当前系统物理内存RAM不足,个人理解这只是一个参考指标,因为在内存ram充足的时候也存在swap的使用,在扩展系统内存的方案里面也存在使用swap,因此通常需要发现问题的时候进行对比参考。
b、buffers
- 概念:用于临时存储数据的内存区域。当系统需要将数据从一个地方传输到另一个地方时,会使用缓冲区来暂时存储这些数据,以提高数据传输的效率。缓冲区通常用于处理I/O操作,比如磁盘读写、网络数据传输等。数据先被写入缓冲区,然后再由系统异步地将数据传输到目标位置,避免了频繁访问实际设备所带来的性能开销。
- 意义:buffers被分配在RAM中,主要针对IO/网络等场景下。
c、cache
- 概念:这里主要指的swap cache,指系统将交换空间(Swap)中的数据缓存到内存中,以便快速访问已经移至交换空间的数据。当系统发现某些数据频繁地被交换到交换空间中(因为物理内存不足等原因),为了提高这些数据的访问速度,系统会将这些数据缓存到内存中,这样下次访问这些数据时就可以更快地获取,而不必每次都从交换空间重新读取。
- 意义:swap cache同buffers一样,他也被分配在RAM中的一段缓存区,但不同的是swap cache里面的缓存数据是专门针对需要和swap交换的内存数据,而buffer里面的缓存数据可能被用于I/O读写/网络数据传输等其他各种场景(PS:个人理解)。
2、命令解读
1)dumpsys meminfo
此命令查询系统当前整体的内存状态,如下先打印了当前的时间搓
C:\Users\Administrator>adb shell dumpsys meminfo
Applications Memory Usage (in Kilobytes):
Uptime: 32351135 Realtime: 85587685
-
Total RSS by Process:展示了系统当前各个进程的RSS使用情况,按照顺序排列
Total RSS by process:
1,203,384K: io.supercent.pizzaidle (pid 4810 / activities)------> PS:此时的前台进程RSS占用1203M
250,004K: system (pid 1445)
160,036K: com.google.android.gms (pid 22458)
158,204K: com.android.systemui (pid 1804)
130,548K: surfaceflinger (pid 786)
127,192K: camerahalserver (pid 1076)
88,844K: com.google.android.gms.persistent (pid 16497)
............
-
Total RSS by OOM adjustment:按照OOM调整的类别来进行展示
Total RSS by OOM adjustment:
848,928K: Native --->下面是native层的进程(包括系统和底层服务),总计848M
130,548K: surfaceflinger (pid 786)
127,192K: camerahalserver (pid 1076)
77,560K: [email protected] (pid 729)
23,808K: zygote64 (pid 716)
14,396K: [email protected] (pid 731)
.........250,004K: System --->下面是系统进程(如system进程,注意systemui不算),总计250M
250,004K: system (pid 1445)
339,500K: Persistent -->持久性进程(如systemui)感觉像是配置了Persistent参数的进程
158,204K: com.android.systemui (pid 1804)
47,072K: com.android.phone (pid 2060)
40,340K: com.android.networkstack.process (pid 1925)
29,560K: com.mediatek.ims (pid 2025)72,824K: Persistent Service -->持久性服务进程
37,052K: com.android.bluetooth (pid 21973)
35,772K: com.google.android.providers.media.module (pid 3149)
1,423,652K: Foreground --->前台进程(通常是用户当前与之交互的应用程序)
1,203,384K: io.supercent.pizzaidle (pid 4810 / activities) --->当前正在玩这个游戏
88,844K: com.google.android.gms.persistent (pid 16497)
71,740K: com.google.android.webview:sandboxed_process0:org.chromium.content.app.SandboxedProcessService0:0 (pid 5275)
59,684K: com.google.android.adservices.api (pid 3890)
962,372K: Visible --->可见进程(但是并没有操作的进程)
160,036K: com.google.android.gms (pid 22458)
194,036K: Perceptible --->这些进程是可察觉的,即用户可以感知到其活动或影响
54,924K: com.google.android.inputmethod.latin (pid 17551)
38,876K: com.google.android.apps.messaging:rcs (pid 16560)
58,364K: Perceptible Medium -->这些进程也是可察觉的,但相对于 Perceptible 类别来说,它们的活动可能更为中等或轻微
58,364K: com.google.android.googlequicksearchbox:search (pid 3543)
46,896K: Backup -->备份进程,在某些情况下可能会执行备份操作
46,896K: com.dpc.plat.appupdate (pid 3056)
43,308K: Previous -->之前的进程,可能指在过去某个时间段内运行过的进程
43,308K: com.google.process.gservices (pid 32449)
181,300K: Cached -->缓存进程,一般用于存储最近使用过的数据或资源以提高访问速度
79,588K: com.hoffnung:remote (pid 6009)
51,536K: com.google.android.permissioncontroller (pid 5059)
- Total RSS by category:按照类别(非进程的角度)来进行展示
Total RSS by category:
1,086,084K: .so mmap ->表示共有 1086M的内存用于动态链接库的内存映射操作
580,804K: GL mtrack ->代表图形库OpenGL内存追踪所占用的内存大小为 580M
466,792K: .art mmap ->表示用于 Android 运行时环境(ART)的内存映射占用
354,016K: EGL mtrack ->指 OpenGL ES 内存追踪占用了 354,016K 的内存量
351,796K: .jar mmap ->表示 Java 程序文件(.jar 文件)的内存映射使用量
313,896K: .oat mmap ->用于优化程序的可执行文件和数据缓存.oat 文件的内存映射
226,636K: Native -->表示本地代码进程所占用的内存
212,288K: Unknown ->未知类型的资源占用
187,164K: Dalvik -->Dalvik 虚拟机相关的资源消耗
181,812K: .apk mmap ->APK 文件的内存映射占用
148,348K: .dex mmap ->可执行文件.dex 文件的内存映射占用
130,448K: Other mmap ->其他类型的内存映射占用
86,284K: Dalvik Other ->Dalvik 虚拟机的其他资源消耗了 86,284K 的内存
70,496K: Other dev ->其他开发相关的资源占用
19,296K: Stack ->栈内存占用了 19,296K 的空间
4,844K: Ashmem ->匿名共享内存(Ashmem)占用了 4,844K 的内存
180K: .ttf mmap ->TrueType 字体文件的内存映射占用了 180K 的内存
0K: Cursor ->游标相关的资源没有占用任何内存
0K: Gfx dev ->图形设备相关的资源也没有占用内存
0K: Other mtrack ->其他内存跟踪资源没有占用内存
- Total PSS by process:同上
- Total PSS by OOM adjustment:同上
- Total PSS by category:同上
- 整体使用情况
Total RAM: 3,697,392K (status normal) ->总共的RAM容量为3697M,这是一台4G手机
Free RAM: 548,930K ( 49,482K cached pss + 448,860K cached kernel + 50,588K free) ->空闲的RAM为 548M(其中包括49M用于缓存 PSS,448M 用于缓存内核,还有 50M是完全空闲的)
DMA-BUF: 119,856K ( 14,080K mapped + 105,776K unmapped) ->表示系统中DMA-BUF的总大小为 119M,它是直接内存访问缓冲区,即不通过cpu将内存映射给用户空间的进程或者硬件设备,其中14M已经映射了,105M还未被映射
DMA-BUF Heaps: 119,808K
DMA-BUF Heaps pool: 75,540K
GPU: 679,348K ( 114,628K dmabuf + 564,720K private) ->GPU占用了679M的内存,其中114M是 DMA-BUF映射而来,564M是GPU独有的
Used RAM: 4,001,150K (2,718,430K used pss + 1,282,720K kernel) ->使用的内存4001M,包括2718M的PSS和1282M的内核内存,这里有个疑问为什么会比总RAM多?
Lost RAM: 182,646K -->丢失的内存
ZRAM: 468,452K physical used for 1,541,632K in swap (2,773,040K total swap)
Tuning: 256 (large 512), oom 322,560K, restore limit 107,520K (high-end-gfx)
疑问1:为什么Used RAM高于Total RAM?
疑问2:DMA-BUF到底是什么?
疑问3:为什么会存在丢失内存?
举个例子
DLS在4G手机启动之前:
Total RSS by process:
266,232K: system (pid 1478)
221,832K: com.google.android.googlequicksearchbox:search (pid 4938)
215,468K: com.android.systemui (pid 20592)
173,252K: com.google.android.apps.messaging (pid 5229)
166,476K: com.google.android.inputmethod.latin (pid 4344)
162,376K: com.google.android.apps.tachyon (pid 5275)
149,084K: com.android.settings (pid 4849)Total RAM: 3,697,392K (status normal)
Free RAM: 1,538,968K ( 569,136K cached pss + 788,280K cached kernel + 181,552K free)
DMA-BUF: 132,776K ( 0K mapped + 132,776K unmapped)
DMA-BUF Heaps: 132,728K
DMA-BUF Heaps pool: 42,672K
GPU: 142,884K ( 99,720K dmabuf + 43,164K private)
Used RAM: 2,352,571K (1,612,199K used pss + 740,372K kernel)
Lost RAM: 270,812K
ZRAM: 241,944K physical used for 815,344K in swap (2,773,040K total swap)
Tuning: 256 (large 512), oom 322,560K, restore limit 107,520K (high-end-gfx)
DLS在4G手机启动之后:
Total RSS by process:
1,884,668K: com.firsttouchgames.dls7 (pid 6643 / activities)
158,388K: surfaceflinger (pid 799)
121,768K: [email protected] (pid 753)
101,680K: system (pid 1478)Total PSS by process:
2,087,176K: com.firsttouchgames.dls7 (pid 6643 / activities)
225,445K: system (pid 1478)
185,186K: surfaceflinger (pid 799)
123,892K: [email protected] (pid 753)Total RAM: 3,697,392K (status normal)
Free RAM: 205,508K (0K cached pss + 168,960K cached kernel + 36,548K free)
DMA-BUF: 170,304K (48K mapped + 170,256K unmapped)
DMA-BUF Heaps: 170,256K
DMA-BUF Heaps pool: 0K
GPU: 1,918,964K ( 152,280K dmabuf + 1,766,684K private)
Used RAM: 4,117,655K (1,632,495K used pss + 2,485,160K kernel)
Lost RAM: 281,699K
ZRAM: 423,156K physical used for 1,381,628K in swap (2,773,040K total swap)
Tuning: 256 (large 512), oom 322,560K, restore limit 107,520K (high-end-gfx)
2)dumpsys meminfo packagename
此命令可以带上包名,查询指定进程的内存详细使用情况,阅读之前先理解《Dirty & Clean & SwapPss》相关概念
C:\Users\Administrator>adb shell dumpsys meminfo io.supercent.pizzaidle
- MEMINFO & App Summary:单位K,反映当前进程两种不同分类的部分占用情况
-
Objects & SQL
3)adb shell free
-
Mem total:真实物理内存RAM的总空间,如上是一台4G内存手机的Mem total
-
Mem used:已经使用的物理内存大小,包括一些缓存内存大小
-
Mem free:空闲的物理内存,他和Mem used之和等于Mem total
-
Mem shared:被多个进程共享的内存大小,例如某个共享so可能被多个进程引用
-
Mem buffers:详细参考《swap & buffers & cache》,为了提升类似IO等传输效率,在RAM开辟的一段缓存区域
-
-/+ buffers/cache:其used表示系统实际使用的内存大小(不包含缓存内存大小),主要区别Mem used
-
Swap Total:磁盘上Swap交换空间总容量
-
Swap used:磁盘上Swap交换空间使用的容量,即代表有多少内存数据存储了进来
-
Swap free:磁盘上Swap交换空间未使用的容量。
理解1:Mem total = Mem used + Mem free;可用物理RAM的总大小,可以分为已经使用的Mem used部分,和没有使用的部分。其中Mem used包括实际进程真实使用的,也包括Mem buffers缓存使用的部分。
理解2:Mem total = buffers/cache used + buffers/cache free;可用物理RAM的总大小,可用分为实际使用的buffers/cache used,和空闲的部分。PS:buffers/cache used代表的大小是去除了mem buffers或者cache相关的, 它与Mem used不同真实反映了各个进程真实使用的大小。
理解3:Mem used = buffers/cache used + Mem buffers;Mem used的计算包括了实际使用的和缓存里面的大小。通过Mem used和buffers/cache used的差异可以看出当前缓存空间的使用情况。
理解4:Swap total = Swap used + Swap free;磁盘Swap空间总大小,可以分为已经使用的used部分,和没有使用的部分。它位于磁盘swap,它的大小可以通过配置来指定,往往和已经固定死的RAM没有什么关联,swap used使用率比较高反映当前可用RAM空间不足。
4)adb shell top
这里暂时只针对top命令的内存相关部分进行介绍,如上图,其展示的指标其实和free基本上一致
Mem total = Mem used + Mem free
Swap total = Swap used + Swap free
PS:在同一台机器同一时刻执行top和free命令,他们之间存在一些偏差,但整体来看是差不多的,个人估计可能是内部使用了不同算法来统计或者根本无法做到同一时刻执行,所以建议这点偏差可以忽略。
5)cat /proc/meminfo
如下命令输出,其结果跟adb shell top比较接近
C:\Users\Administrator>adb shell cat /proc/meminfo
MemTotal: 3697392 kB
MemFree: 83888 kB
MemAvailable: 1368764 kB
Buffers: 2164 kB
Cached: 1308024 kB
SwapCached: 144664 kB
Active: 855264 kB
Inactive: 1243924 kB
Active(anon): 341388 kB
Inactive(anon): 552064 kB
Active(file): 513876 kB ^
Inactive(file): 691860 kB
Unevictable: 90340 kB
Mlocked: 90340 kB
SwapTotal: 2773040 kB
SwapFree: 1819848 kB
Dirty: 52 kB
Writeback: 0 kB
AnonPages: 860336 kB
Mapped: 707324 kB
Shmem: 20412 kB
KReclaimable: 175176 kB
Slab: 400312 kB
SReclaimable: 139980 kB
SUnreclaim: 260332 kB
KernelStack: 57760 kB
ShadowCallStack: 14476 kB
PageTables: 101824 kB
NFS_Unstable: 0 kB
Bounce: 0 kB
WritebackTmp: 0 kB
CommitLimit: 4621736 kB
Committed_AS: 69377560 kB
VmallocTotal: 259653632 kB
VmallocUsed: 226572 kB
VmallocChunk: 0 kB
Percpu: 77184 kB
AnonHugePages: 0 kB
ShmemHugePages: 0 kB
ShmemPmdMapped: 0 kB
FileHugePages: 0 kB
FilePmdMapped: 0 kB
CmaTotal: 409600 kB
CmaFree: 5252 kB
- MemTotal:所有可用RAM内存大小,即物理内存容量减去一些预留位(所以整体比实际物理内存容量小)。系统从加电开始到引导完成,引导程序、内核等需要保留一些内存空间,最后剩下的MemTotal,他在系统运行期间保持恒定不变的。
- MemFree:没有使用的空闲内存总容量
- MemAvailable:可以被应用程序使用的内容总容量。系统中虽然有些内存已经被使用了,但是可以进行回收,例如cache/buffers、slab等,所以MemFree并不能代表当前还能够提供多少内存空间给应用程序。即MemAvailable约等于MemFree + buffers + cached,它是内核使用的特定算法估算出来的一个值。
参考cat /proc/meminfo 各字段详解_cat proc meminfo-CSDN博客
参考Linux的缓存内存(cache memory)_linux cache-CSDN博客
3、LWKD
LWKD全称lowmemorykiller,其工作原理可以参考Low Memory Killer(一) - android源码分析 - 简书
如上经典日志,lowmemorykiller非常活跃,进行疯狂查杀优先级低的进程,其中可以看到圈红的地方:
- adj为0的进程都已经开始被查杀了,说明当前内存的压力已经很大了(lwkd通过adj给android所有进程进行分类,从优先级最低的空进程/缓存进程到优先级很高的前台进程和系统核心进程,adj依次减小,详情可以参考Android系统为什么lmkd杀到adj 100就代表有低内存?_lmkd adj-CSDN博客)
- reason为被kill的原因,如果是low watermark通常为内存压力超过了配置的内存水位线,这个时候也表示内存压力大,当然我们可以动态调节这个水位线,并不是越高越好也不是越低越好,这个值通常需要多方测试取一个平衡的值。
1)oom_odj
adb shell dumpsys meminfo
adb shell dumpsys activity lru
adb shell dumpsys activity processes
2)killinfo
lwkd在system/memory/lmkd/event.logtags文件中定义了一些event事件,此文件可能存在多份,一定要查清楚当前项目使用的是那一份,定义格式如下:
# The entries in this file map a sparse set of log tag numbers to tag names.
# This is installed on the device, in /system/etc, and parsed by logcat.
#
# Tag numbers are decimal integers, from 0 to 2^31. (Let's leave the
# negative values alone for now.)
#
# Tag names are one or more ASCII letters and numbers or underscores, i.e.
# "[A-Z][a-z][0-9]_". Do not include spaces or punctuation (the former
# impacts log readability, the latter makes regex searches more annoying).
#
# Tag numbers and names are separated by whitespace. Blank lines and lines
# starting with '#' are ignored.
#
# Optionally, after the tag names can be put a description for the value(s)
# of the tag. Description are in the format
# (<name>|data type[|data unit])
# Multiple values are separated by commas.
#
# The data type is a number from the following values:
# 1: int32_t
# 2: int64_t
# 3: string
# 4: list
# 5: float
#
# The data unit is a number taken from the following list:
# 1: Number of objects
# 2: Number of bytes
# 3: Number of milliseconds
# 4: Number of allocations
# 5: Id
# 6: Percent
# s: Number of seconds (monotonic time)
# Default value for data of type int/long is 2 (bytes).
#
# TODO: generate ".java" and ".h" files with integer constants from this file.
# for killinfo logs
10195355 killinfo (Pid|1|5),(Uid|1|5),(OomAdj|1),(MinOomAdj|1),(TaskSize|1),(enum kill_reasons|1|5),(MemTotal|1),(MemFree|1),(MemAvailable|1),(Cached|1),(SwapCached|1),(Buffers|1),(Shmem|1),(Unevictable|1),(Mlocked|1),(SwapTotal|1),(SwapFree|1),(ActiveAnon|1),(InactiveAnon|1),(ActiveFile|1),(InactiveFile|1),(SReclaimable|1),(SUnreclaim|1),(KernelStack|1),(PageTables|1),(IonHeap|1),(IonHeapPool|1),(CmaFree|1),(MsSinceEvent|1),(MsSincePrevWakeup|1),(WakeupsSinceEvent|1),(SkippedWakeups|1),(TaskSwapSize|1),(GPU|1),(Thrashing|1),(MaxThrashing|1),(PsiMemSome|5),(PsiMemFull|5),(PsiIoSome|5),(PsiIoFull|5),(PsiCpuSome|5)
上文不是很好看,可用如下几个步骤将其转换为表格:
步骤一:提取event日志中的killinfo信息
grep --color -iE "killinfo" logcat_events_2024_0904_1811.log > killinfo.txt
步骤二:使用Notepad++直接进行替换分隔符为\t
步骤三:将其复制到表格中,并将event.logtags中的信息作为标头,最后形成如下表格
4、PSI
PSI全称Pressure Stall Information,提供了一种评估系统资源压力的方法,它提供了一种实时检测系统资源竞争程度的方法,以竞争等待时间的方式呈现。简单的可以理解为“任务因资源短缺而延时的时间占比”。详情参考
Getting Started with PSI · PSI
full:表示在某段时间内,所有进程或者任务等待某资源耗时占比
some:表示某段时间内,单个进程或者任务等待某资源耗时最长的占比
其中某资源通常有三类资源:IO、memory、CPU,其中CPU不可能存在full,因为无论任何时刻CPU总在执行某个任务,否则该系统已经宕机
注意:他们的值表示单位时间段内的百分比,例如假设full为10.0,单位时间长度为10秒,那么表示所有任务等待某资源耗时了1秒,可用抽线的理解为系统此资源短缺阻塞了1秒的时长。
1)ANR的PSI值
如上avg10的时候memory和IO的Some PSI值达到了90%以上,Full PSI值达到了40%以上,表示有进程等待memory/IO资源超过9秒,有4秒的时间是所有进程都等待不了memory/IO资源,表示当前系统负载比较高
2)LWKD的PSI值
通常可以认为LWKD里面的PSI超过10,此时系统资源压力比较高,但同时也需要结合killinfo其他指标综合分析。
如下一份killinfo转换之后,可以根据事件判断swap越来越低,但是内存压力并不大,SUnreclaim占用比较高,说明可能存在kernel内存泄漏
为什么swap剩余空间低但是内存压力并不大?
为什么SUnreclaim指标指向内存泄漏?
二、IO相关
1、基本概念
2、命令解读
1)vmstat
三、GPU相关
GPU 指的是 Graphics Processing Unit,即图形处理单元。GPU 是一种专门用于处理图形和图像相关计算任务的处理器,广泛应用于图形渲染、游戏设计、视频编辑、科学计算等领域。
与传统的中央处理单元(CPU)相比,GPU 在处理大规模并行计算时表现更加出色。GPU 可以同时处理多个数据流,执行大量相似的计算任务,适合处理需要高度并行计算能力的工作负载。
在图形应用方面,GPU 通常被用于加速三维图形渲染,使得游戏、虚拟现实(VR)、电影特效等内容的表现更加流畅和真实。此外,GPU 也被广泛应用于机器学习、人工智能等领域,用于加速深度学习网络的训练和推断过程。
1、GPU基本信息
可以通过如下命令获取当前手机的GPU基本信息:
adb shell "dumpsys SurfaceFlinger | grep "GLES""
如上可以分为三部分,其中第一部分可以理解为此GPU生产公司,ARM表示此GPU采用了ARM架构,Imagination Technologies为另一个平台或者公司的架构,通常简称为IMG
可以通过如下命令伪造GPU基本信息:
adb root
adb shell "setprop vendor.debug.gpud.enable '1'"
adb shell "setprop vendor.debug.gpud.process.name ''"
adb shell "setprop vendor.debug.gpud.gl.vendor 'ARM'"
adb shell "setprop vendor.debug.gpud.gl.renderer 'Mali-G52 MC2'"
adb shell "stop;start"
adb shell "dumpsys SurfaceFlinger | grep "GLES""
2、GPU内存信息
可以通过如下命令获取GPU内存相关信息:
adb shell cat proc/mtk_mali/gpu_memory //此条命令只针对MTK,不同平台路径不一样
- 第一行mali0 141867表示第一块GPU暂时代名为mali0,其总共使用了141867个内存页,注意单位是页,因此转换为kb的计算方法:141867 * 4 = 567468 kb。注意他不是gpu内存容量大小,而是统计了当前系统所有使用gpu mali0的进程的内存页数之和,因此它的数值也是实时在变化。
- 之后的kctx,表示一个 Kernel Context,具有 ID 0x0000000061e8bc12(可能是某个进程的句柄对象的HASH值)。其中红色框部分表示每个kctx(进程)使用了gpu内存页数,所有的kctx的内存页数之和等于mali0的内存页个数;后面绿色框部分表示每个kctx对应的进程PID,大多数进程通常只会存在一个kctx,但是也有个别应用或者进程拥有多个kctx,例如上图中的PID为25212进程。
3、经典案例
案例一:GPU伪造信息方案
问题描述:com.wemade.mir4global游戏在google play第一次启动的时候出现不支持纹理的提示框,且游戏界面人物显示异常打上了马赛克
问题分析:此游戏在google等对比机上面能够正常使用和显示,并没有此类弹框,根据弹框可以支持提示的此平台的opengl部分纹理格式,且有如下异常日志
最后结论:经过大量测试发现此现象只出现在IMG平台上,MTK做了如下实验,将img的gpu fake to mali(fake的意思就是伪造GPU的型号信息,即三方应用读取GPU的型号出来就不再是IMG二手MAILI)之后就能正常启动
问题总结:此题是APP问题,fake GPU以后游戏显示正常。所以和DDK修改无关。fake GPU有效果。是APP将img的gpu fake to mali的,游戏显示正常了。是MIR4对GPU的型号做了区分,所以表现形式不一样
修改方案:通过代码方式伪造GPU信息为ARM:
案例二:GPU内存统计算法
问题描述:Pizza Ready 12.0.0 Screen record in Game mode assist disappear after playing
问题分析:在Android 14的手机上玩Pizza Ready游戏过程中,出现screen record进程被杀,此时dump了该应用内存使用情况,并与对比机进行了对比,发现GL占用相差500M
后对比了多款机器此应用adb shell dumpsys meminfo io.supercent.pizzaidle的表现如下,从此结果可以看出来在Dimensity 6300+kernel 5.15+android 14的平台上必现,在Helio系列的机器均不出现,初步怀疑此问题为平台基线共性问题
后对比了多款机器在其他应用的表现,是否也存在差异如下表,从此表结果可以看出pizzaidle单独应用存在:
最后MTK和Arm给到的回复为GPU统计BUG,即pizzaidle存在多个kctx,之前的统计方式只计算了第一个kctx,因此只有几M,后加入修复patch,轮询统计某进程对应的所有kctx,所以计算出来有500多M,patch如下:
转载自CSDN-专业IT技术社区
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/qq_27672101/article/details/140658955