搜索
您的当前位置:首页Kernel Memory分解

Kernel Memory分解

来源:乌哈旅游

1.计算公式

MEMINFO_SHMEM + MEMINFO_SLAB_UNRECLAIMABLE + MEMINFO_PAGE_TABLES + MEMINFO_VM_ALLOC_USED + MEMINFO_KERNEL_STACK(Optional) + ionUnmapped/dmabufUnmapped(After Android S) + gpuPrivateUsage(After Android T)

读取:Used RAM's kernel from dumpsys.meminfo

2.组成及优化方法

2.1. MEMINFO_SHMEM

cat /proc/meminfo =>Shmem

被各个进程共享的内存页的数量,Shmem统计的内容包括:shared memory

  • SysV shared memory [shmget etc.]
  • POSIX shared memory [shm_open etc.]
  • shared anonymous mmap [ mmap(…MAP_ANONYMOUS|MAP_SHARED…)]
  • tmpfs和devtmpfs。

注:所有tmpfs类型的文件系统占用的空间都计入共享内存,devtmpfs是/dev文件系统的类型,/dev/下所有的文件占用的空间也属于共享内存。可以用ls和du命令查看。
如果文件在没有关闭的情况下被删除,空间仍然不会释放,shmem不会减小。

2.2. MEMINFO_SLAB_UNRECLAIMABLE

cat /proc/meminfo => SUnreclaim

Slab中不可回收的量,同process数量有关,可考虑减少process or task,如果无法定位,参考slab debug的方法进行拆解,分析slab占用内存细节以及slab leak。

2.2.1. 内核通过slab 机制分配内存,如果发现meminfo里slab占用内存过高, 如何细化分析哪些模块占用slab内存高,有没有存在leak?

如下方法可用:

2.2.1.1. 配置相应的宏控

CONFIG_SLUB_DEBUG_ON=y (eng版本默认开启)

CONFIG_MTK_MEMCFG=y (默认都有开启)

若需要查看4k, 8k大小的slab的backtrace,需要额外开启以下宏:  

CONFIG_PAGER_OWNER=on
CONFIG_PAGER_OWNER_SLIM=on

参考后面的如何查询内核所有page的使用情况?

注意a : ago project需移除以下红字部分
/kernel-xx/init/Kconfig
config SLUB_DEBUG
default y
bool "Enable SLUB debugging support" if EXPERT
depends on SLUB && SYSFS
- depends on !MTK_ENABLE_AGO

注意b : user/userdebug 需移除以下红字部分

/kernel-xx/drivers/misc/mediatek/mem/mtk_memcfg.c

-#ifdef CONFIG_MTK_ENG_BUILD
/* memblock reserved */
entry = proc_create("memblock_reserved", 0644,
mtk_memcfg_dir,
&mtk_memcfg_memblock_reserved_operations);
if (!entry)
pr_info("create memblock_reserved proc entry failed\n");
pr_info("create memblock_reserved proc entry success!!!!!\n");
#ifdef CONFIG_SLUB_DEBUG
/* slabtrace - full slub object backtrace */
entry = proc_create("slabtrace",
0400, mtk_memcfg_dir,
&proc_slabtrace_operations);

if (!entry)
pr_info("create slabtrace proc entry failed\n");
#endif
-#endif /* end of CONFIG_MTK_ENG_BUILD */

2.2.1.2. 查看各slab分配方式占用大小以及各个slab使用者的backtrace

2.2.1.2.1.cat /proc/slabinfo“ >> slabinfo1.txt
查看各种slab分配方式占用大小,如下图

2.2.1.2.2.cat /proc/mtk_memcfg/slabtrace" >> slabtrace1.txt
查看各个slab使用者backtrace,如下图

第一个数字表示allocate 次数,乘上slab obj size即为占用内存, 越大表示占用越多。

注意kmalloc-4096以上为page单位,backtrace信息需要通过page owner debug方式查看,参考下面的如何查询内核所有page的使用情况?

2.2.1.3. 重复步骤2.2.1.2

持续关注slabtrace 是否有明显增长的backtrace, 即可能为泄露点。

2.2.2. 如何查询内核所有page的使用情况?

page owner用于跟踪每个页面的分配者,可用来调试内存泄漏或查找内存占用。

当分配发生时,有关分配的信息(如调用堆栈和页面顺序)存储在每个页面的特定存储中。

当需要了解所有页面的状态时,就可以获取并分析这些信息。
Page owner功能开启:

2.2.2.1. 确保kernel config有打开下面的宏

CONFIG_PAGE_OWNER=y

2.2.2.2. 修改 dts 文件

增加page_owner=on和stack_depot_disable=off两个配置,参考如下:

diff --git a/arch/arm64/boot/dts/mediatek/mt68XX.dts b/arch/arm64/boot/dts/mediatek/mt68XX.dts
index 498596497314..3d579c069a38 100644
--- a/arch/arm64/boot/dts/mediatek/mt68XX.dts
+++ b/arch/arm64/boot/dts/mediatek/mt68XX.dts
@@ -603,6 +603,7 @@ chosen: chosen {
 			    loglevel=8 \
 			    8250.nr_uarts=4 \
 			    androidboot.hardware=mt6855 \
+			    page_owner=on stack_depot_disable=off \
 			    initcall_debug=1 transparent_hugepage=never \
 			    vmalloc=400M swiotlb=noforce allow_file_spec_access \
 			    firmware_class.path=/vendor/firmware pelt=8 \

2.2.2.3. 如何判断是否已经成功的开启page owner

查看cmdline 中是否包含 ”page_owner=on” 信息
adb shell "cat /proc/cmdline"
抓取page owner 数据
adb shell "cat sys/kernel/debug/page_owner" > page_owner_full.txt 
解析 page_owner信息
通过 tool 快速解析出申请内存大的top进程pid,tool release需要提case给MTK去申请 page_owner_analysis_tool
// --- end 如何查询内核所有page的使用情况?

2.2.3. 另外slab leak 也可以通过kmemleak debug机制查询:

kmemleak可以追踪kmalloc(), vmalloc(), kmem_cache_alloc()等函数引起的内存泄漏,一般用于slab内存泄漏。

2.2.3.1. 打开kmemleak

开启如下kernel宏控:
CONFIG_DEBUG_KMEMLEAK=y
CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF=n
CONFIG_DEBUG_KMEMLEAK_EARLY_LOG_SIZE=40000
然后在.config中确认下是否已开启。

2.2.3.2. 查看是否开启kmemleak

修改内核配置后adb shell,看是否存在sys/kernel/debug/kmemleak这个节点,如果存在表明已经开启kmemleak。

2.2.3.3. 使用kmemleak

第一次scan:
echo scan > sys/kernel/debug/kmemleak // 开始扫描
然后cat sys/kernel/debug/kmemleak // 会得到很多backtrace,但是这其中有些是误抓的(kmemleak存在误报情况)
然后echo clear > sys/kernel/debug/kmemleak // 清除log
第二次scan:echo scan > sys/kernel/debug/kmemleak //开始扫描
过段时间等待leak的积累,然后 cat sys/kernel/debug/kmemleak
很多第一次误报的backtrace没有了,会得到很多重复的backtrace
重复的backtrace会越来越多,不断增长,一般这里就是内存泄露的点

2.2.3.4. 报错实例

如下是一个测试的驱动,在驱动的init函数中通过kmalloc分配256字节内存而不释放,按照步骤2.1.3.3. 操作,可以捕获如下疑似的内存泄露,具体是否有内存泄漏还需要结合代码来确认。
# cat /sys/kernel/debug/kmemleak
unreferenced object 0xffffffc164ac0900 (size 256):
comm "insmod", pid 7382, jiffies 4312832123 (age 1532.396s)
hex dump (first 32 bytes):
34 12 00 00 c1 ff ff ff 18 00 00 00 00 00 00 00 4...............
ff ff ff ff ff ff ff ff 00 00 00 00 00 00 00 00 ................
backtrace:
[<000000004c509bf2>] kmem_cache_alloc_trace+0x278/0x33c
[<0000000006a54715>] 0xffffffaad42b1054
[<000000000320f832>] do_one_initcall+0x124/0x2b0
[<000000006c1849e9>] do_init_module+0x5c/0x260
[<00000000c68acdc4>] load_module+0x3074/0x3854
[<00000000e88a046b>] __arm64_sys_finit_module+0xec/0x11c
[<000000009384af7d>] el0_svc_common+0xa0/0x170
[<000000001d388de9>] el0_svc_handler+0x68/0x84
[<0000000083267d56>] el0_svc+0x8/0x300
[<00000000da66104e>] 0xffffffffffffffff

2.3.MEMINFO_VM_ALLOC_USED

cat /proc/meminfo =>VmallocUsed
vmalloc已经使用的内存量,使用cat /proc/vmallocinfo进一步拆分(EasyMemory Parse Tool解析表格中“Vmalloc”页面)。可参考上面如何查询内核所有page的使用情况?

2.4.MEMINFO_PAGE_TABLES

cat /proc/meminfo =>PageTables

同process or task 数量有关,数据太大,则可考虑减少process or task。

2.5.MEMINFO_KERNEL_STACK

cat /proc/meminfo => KernelStack
每一个用户线程都会分配一个kernel stack(内核栈),内核栈虽然属于线程,但用户态的代码不能访问,只有通过系统调用(syscall)、自陷(trap)或异常(exception)进入内核态的时候才会用到,也就是说内核栈是给kernel code使用的。

Kernel stack(内核栈)是常驻内存的,既不包括在LRU lists里,也不包括在进程的RSS/PSS内存里,是属于kernel消耗的内存。
(Currently the CONFIG_VMAP_STACK of the project is enabled, so it does not need to be counted in the kernel space)

2.6.ionUnmapped/dmabufUnmapped

ION unmapped or DMABUF unmapped from dumpsys.meminfo.txt (After Android S)
参考后面的 DMABUF/EGL/ION 进一步拆分,找到用量较大的process owner进行针对优化。

2.7.gpuPrivateUsage

GPU private from dumpsys.meminfo.txt (After Android T)
和显示屏size、density以及刷新率相关,在对齐这些设定的基础上参考后面的GPU/GL track进一步拆分。

3. 优化方法

使用EasyMemory Parse Tool中的showinfo.bat脚本进行抓取,后续使用EasyMemory Parse Tool进行解析,参考EasyMemory Parse Tool使用方法。重点查看Summary页面"Kernel used"部分中各个子项的差别。除了上面步骤2中所说优化的方法外,再针对SUnreclaim和VmallocUsed进一步拆分优化的方法进行说明。

3.1. SUnreclaim

3.1.1. 抓取slabinfo信息找到差异项

/proc/slabinfo的信息按照<num_objs>*<objsize>的大小进行排序(单位是byte,可以 <num_objs>*<objsize>/(1024*1024)换算成MB);
上面排序的slab,只需要比较unreclaim部分,这个需要在代码中确认,可以通过搜索kmem_cache_create("XXX"
比如inode_cache:
inode_cachep = kmem_cache_create("inode_cache",
                                                          sizeof(struct inode),
                                                          0,
                                                          (SLAB_RECLAIM_ACCOUNT|SLAB_PANIC|
                                                           SLAB_MEM_SPREAD|SLAB_ACCOUNT),
                                                           init_once);
带flag SLAB_RECLAIM_ACCOUNT的就是可回收的slab,不带的就是要排查的unreclaim slab。

3.1.1.1.先根据上面两步比对出最大差异的unreclaim slab,之后再在slab backtrace中查找差异项对应目录下具体的user是谁。
3.1.1.2.kernel-5.10之前可以参考上面表格中的两条FAQ进行debug

kernel-5.10及之后开启slab backtrace的方法如下

前置条件:user/userdebug load,开启root+mount权限

a. 确认config是否有打开:
zcat proc/config.gz | grep SLUB
CONFIG_SLUB_DEBUG=y

c. 确认特定slab的alloc_traces,这部分需要对应的owner去评估是否可以缩减。

cat /sys/kernel/debug/slab/kmalloc-128/alloc_traces
此步中的kmalloc-128是根据之前拆分出来需要排查的差异项。

d. (If need)Enable /sys/kernel/debug/slab/ to show allocate backtrace of kmalloc-2k, kmalloc-4k, kmalloc-8k

Set higher_order_disable = false @ parse_slub_debug_flags in kernel-5.10/mm/slub.c

  • Replace preloader_xxx.bin to preloader_xxx_SBOOT_DIS.bin
  • Replace boot.img to boot_debug.img

3.2. VmallocUsed

常见VmallocUsed差异项厘清见下表

Item优化说明
Load modulelsmod 命令查看载入module数量及大小
优化方向:考虑disable不需要的module or module优化
__cfi_check [cqhci]CONFIG_CFI_CLANG=y @gki_defconfig,disable可优化9MB,关掉后没有call flow完整性check,会有security风险和漏洞
f2fs_build_segment_manager

ROM size不同会影响此项大小,建议配置对齐进行比较,如需进一步厘清需请storage owner确认

apummu_mem_alloc

可以改为动态开关,不必开机使用,具体可咨询AI owner

dup_task_struct / _do_fork + fork_idle

kernel thread数量
优化方向:比较 ps -t的log,找出thread差异

pcpu_balance_workfn
mmprofile_init_buffer
kernel升版导致,具体差异量可提交eService咨询
disksize_store跟proc/meminfo的SwapTotal正相关,会跟DRAM大小(12GB or 16GB) & ZRAM Swap比例(55% or 75%)相关,建议配置对齐进行比较

如不在上述范围内,需要进一步debug,需要打开page_owner进行细项拆分:

3.2.1. user/userdebug load,开启root+mount权限,参考如下方式打开page_owner

diff --git a/arch/arm64/boot/dts/mediatek/mt6855.dts b/arch/arm64/boot/dts/mediatek/mt6855.dts

index 498596497314..3d579c069a38 100644
--- a/arch/arm64/boot/dts/mediatek/mt6855.dts
+++ b/arch/arm64/boot/dts/mediatek/mt6855.dts

@@ -603,6 +603,7 @@ chosen: chosen {
           loglevel=8 \
           8250.nr_uarts=4 \
           androidboot.hardware=mt6855 \
+          page_owner=on stack_depot_disable=off \
           initcall_debug=1 transparent_hugepage=never \
           vmalloc=400M swiotlb=noforce allow_file_spec_access \
           firmware_class.path=/vendor/firmware pelt=8 \

3.2.2. 编译后,执行如下命令确认page_owner 是否有成功打开

adb shell "cat /proc/cmdline" 中是否有包含 page_owner 信息。

3.2.3. 抓取page_owner信息

adb shell "cat /sys/kernel/debug/page_owner" > page_owner

4. DMABUF/EGL/ION

4.1. EGL用量统计

Kernel-5.10之前EGL统计的是ION内存部分,之后统计的是DMABUF部分。

MTK提供的统计节点在对EGL统计时,统计了进程使用DMABUF的PSS或RSS。
如果仅统计到PSS会无法统计到进程占用的所有DMABUF;而统计到的RSS则会统计了unmapped 和 mapped 的DMABUF用量。由于在不同的机型上使用了PSS或RSS统计方式,会导致出现EGL用量统计为0或过大的情况。

后续优化方向,采取使用fd_cnt均摊方式进行统计,让DMABUF用量平均分摊在相关process身上,预计kernel-6.x会有改进版。
kernel-5.10后版本EGL采用RSS的统计方式

因dmabuf rss_pid的PSS栏位,会去判断gralloc dmabuf的mmap or unmmap状态。

如link 中的介绍:


 

由于目前Mali gralloc policy和IMG gralloc policy都改成需要使用dmabuf才去mmap,会导致EGL mtrack读取PSS栏位(depends on mmap gralloc)沒有值。

修正方式为EGL mtrack读取RSS栏位,就不会受到gralloc mmap or unmmap影响。

影响:

单个process的 EGL memory 统计会偏大, 同样total EGL 也会偏大。 

但是EGL mtrack过大,不会影响整体used RAM的计算 , 因为在计算used RAM 时会把EGL mtrack减掉:
 Total EGL mtrack = sum (process EGL mtrack)

4.2. Used PSS 的计算方式

  • Kernel 5.10后:
    dumpsys meminfo的used pss = SUM 各 process (不含cache) - EGL mtrack + DMA-BUF mapped - GL mtrack (p.s. GL mtrack算在Kernel)
  • Kernel 4.19及之前:
    dumpsys meminfo的used pss = SUM 各 process (不含cache) - EGL mtrack + ION mapped

不建议直接改回 PSS 的计算方式,否则在检查单个process EGL mtrack去检查leak测试时,会有检测不到的问题。

但因采用RSS的方式,导致total EGL mtrack 偏大,导致失真严重。所以可以用DMA - BUF的值来做简单的参考,但是因为该值有包含kernel driver分配的dmabuf,所以也会比实际的EGL PSS 计算的要偏大一点。

采用PSS计算和 RSS 计算的两种修改方法:

4.3. EGL用量优化方法

获取DMABUF的指令

adb root
adb shell cat /proc/memtrack > proc.memtrack.EGL.txt
adb shell "dmabuf_dump" > dmabuf_dump.txt
adb shell cat /proc/dma_heap/all_heaps > dmaheap_all_heaps.txt

​此部分指令释义可以看后面ION对应指令说明。

4.4. 推荐方法

使用EasyMemory Parse Tool中的showinfo.bat脚本进行抓取,后续使用EasyMemory Parse Tool进行比对解析,参考EasyMemory Parse Tool使用方法。

主要查看“DMABUF summary”和“DMABUF”页面的数据进行分析。

“DMABUF summary”页面用于check 各process的总量:

DMABUF”页面可以查看每个process中DMABUF用量的具体细节:

可根据表格中的差异,找到需要优化的进程及差异点,再找对应进程owner进一步确认优化。

5. ION(kernel-4.19及之前使用)

5.1.ION的设计目标

为了避免内存碎片化或者为一些有着特殊内存需求的硬件,比如GPUs、display controller以及camera等,在系统启动的时候,会为他们预留一些memory pools,这些memory pools就由ION来管理。 通过ION就可以在硬件以及user space之间实现zero-copy的内存share.

5.2. 如何查看ION使用内存指令

5.2.1. 查看ion内存总用量

adb shell dumpsys meminfo

该指令可以获取整个系统的memory使用状态,其中EGL部分代表的ION使用量。可以通过查看该部分的使用状态来确认ION是否使用异常。

如果EGL使用量较多,则可以进入第5.2.2步继续确认。

5.2.2. ion使用量内存详情

adb shell cat /d/ion/ion_mm_heap > ion_mm.log

或者查看aee 里面的sys_ion_mm_heap。
ion_mm_heap有几个段,每个段有不同的用途,下面一一讲解格式:

5.2.2.1. 如下信息各列所代表的含义分别是:
client( dbg_name) pid size address
----------------------------------------------------
ndroid.settings( gralloc) 1638 4816896 0xffffffc02c813c00
ndroid.systemui( gralloc) 1448 7016448 0xffffffc02e2e3000
droid.launcher3( gralloc) 1969 29884416 0xffffffc0330dda00
system_server( gralloc) 1186 4816896 0xffffffc035fcb500

从这部分可以了解ION的各个client的使用状况。从中可以找出size异常多的module owner来分析,client之间能share同一块buffer;如果要了解buffer的详细状况,可以通过如下步骤继续分析:

5.2.2.2. memory leakage buffer 信息

mtk_ion_test, 是最近访问这个buffer的user
2598是user pid, 8392704是buffer size
最后的total orphaned是总共leakage size

orphaned allocations (info is from last known client):
mtk_ion_test 3009 1048576 0 1
----------------------------------------------------
total orphaned 1048576
5.2.2.3. ion 目前正在使用的buffer size,包含mm, camera, va2mva heap, 
total 70365184

了解ION total值

请先确认后面的5.2.2.7中是否有orphaned的buffer。如果没有, 且该部分的total比较大, 可以从前面的5.2.2.1中找size比较大, 再从后面的5.2.2.8 的区间看它的client中去看哪个buffer alloc/share 的时间比较久。

5.2.2.4. camera heap的buffer的size

下面的cam-va2mva是camera heap和va map mva这两个heap的size

cam-va2mva total 0 0

deferred free 0
5.2.2.5. ion 几个pool里面的memory, 可以只看"pool=" 后面的数字, 单位是byte
----------------------------------------------------

0 order 4 highmem pages in pool = 0 total, dev, 0xffffffc03c7c2f00, heap id: 10
469 order 4 lowmem pages in pool = 30736384 total
5.2.2.6. ion buffer的信息其中hdl是buffer 被几个user 使用

buffer size kmap ref hdl mod mva sec flag pid comm(client) v1 v2 v3 v4 dbg_name

0x187462bb   139264   0   4   3   0   1 25165824(  0)   0(  0) 0x0, 0x0,   478(  478)  allocator@2.0-s 0x500 0x4 0xa5ffba1c 0x2bc StatusBar#0

0x46bb5f4f   278528   0   4   3   0   1 33554432(  0)   0(  0) 0x0, 0x0,   478(  478)  allocator@2.0-s 0x500 0x8 0xa5ffbe14 0x284 NavigationBar0#0

0x8798e15c    16384   0   2   1  -1   0   0(  0)   0(  0) 0x0, 0x0,   478(  478)  allocator@2.0-s 0x0 0x0 0x0 0x0 nothing

从该部分中了解buffer的size, alloc buffer的pid ("alloc_pid"字段), 最近访问的pid和进程名("pid"和"comm(client) "字段)。

最后一列一般指向是谁使用了该buffer。

若为nothing表示无debug信息,需要添加debug信息参考如下:

在create ION调用接口上都在第一个参数传入buffer所属的owner name,如"fpipe.async"(具体由实际调用者传入其name),

mBufferPool = ImageBufferPool::create("fpipe.async", mInputInfo.mSize, mInputInfo.mFormat, ImageBufferPool::USAGE_HW);

ion set debug name的方式参考如下. 其中dbg name是字符数组,最长有效长度为 48 - 1 

// #define ION_MM_DBG_NAME_LEN 48

value1 – value 4都是unsigned int,这四个值也可以作为详细区分参考。

5.2.2.7. android O版本之后才有)orphan buffer的信息, 有buffer的地址, alloc这个buffer的pid和ion user name, 后面的pid, tgid,process是fd leakage的process的信息及leakage的fd)
-----orphaned buffer list:------------------

buffer alloc_pid alloc_client pid tgid process fd

0xffffffc022b29e00 3007 ion_test 3007 3007 mtk_ion_test 4

从该部分可以了解是否有orphaned buffer, 这个buffer是谁alloc的, leakage的pid是多少, buffer的fd是多少, 然后从上面5.2.2.6的pid(alloc_pid) comm(client) 这几个字段可以了解到最近access这个buffer的user的pid和process name; 可以提供这个信息给上面5.2.2.6中fd leakage的process进行分析。

泄漏判断

基本上一块ion内存都有对应的fd,因此ion泄漏伴随着fd泄漏,可以通过查看:

cat /proc/$pid/file_state

db里的PROCESS_FILE_STATE

搜索anon_inode:dmabuf关键字,应该可以看到非常多,比如:

Search "anon_inode:dmabuf" (943 hits in 1 file)

 D:\PROCESS_FILE_STATE (943 hits)

 Line 5: lrwx------ 1 cameraserver audio 64 2016-01-01 00:48 100 -> anon_inode:dmabuf

 Line 6: lrwx------ 1 cameraserver audio 64 2016-01-01 02:32 1000 -> anon_inode:dmabuf

上面的例子可以看到anon_inode:dmabuf fd有943个,存在泄漏。

另外看/proc/$pid/maps或db里的PROCESS_MAPS,搜索anon_inode:dmabuf,一样可以搜索到很多:

Search "anon_inode:dmabuf" (880 hits in 1 file)

 D:\PROCESS_MAPS (880 hits)

 Line 22: c6c43000-c7102000 r--s 00000000 00:0a 8524 anon_inode:dmabuf

 Line 23: c7102000-c75c1000 r--s 00000000 00:0a 8524 anon_inode:dmabuf

5.2.2.8. 各个client 使用的buffer状况, 其中fd是这个user的这个buffer的share fd, ts是buffer alloc或import的时间

client(0xffffffc02c813c00) ndroid.settings(gralloc) pid(1638) ================> handle=0xffffffc031469e80,buffer=0xffffffc02f310900, heap=10,fd= 53, ts: 16120ms

从该部分看到各个client buffer的详细状况, seach client下各个buffer的address(如上面示例中的0xffffffc02f310900), 就可以看到这个buffer被哪些client在share同一块使用,另外还可以在上面5.2.2.6中确认该buffer真正的owner是谁。

5.2.2.9. dump的时间
current time 38252 ms, total:         70365184!!

可以用来比较aee里面的时间,如果差别比较远,这个dump参考价值可能不大,需要看sys_ion_client_history里面client aee对应时间点的信息。

5.3. 查看个别进程使用ion内存

adb shell cat /d/ion/clients/clients_summary

作用:summary of all clients。

5.4. 查看ion使用历史

adb shell cat /d/ion/client_history > client_history

作用:This is a thread to record the allocation and free event of all kind of heap type,  from kernel boot up;Ion_alloc() and ion_free() will kick the thread named “ion_history” to update client_history 

在第5.2步中定位使用ION过大或异常的client之后,再在该文件中搜索client name,看其ion占用是否有变化。

5.5.关于ION buffer Memory leakage

ion share产生的file都调用ion_share_close关闭了,但是还有以下一些可能会导致buffer指向的share fd无法关闭,这部分必须要保证也关闭,buffer才可以被回收:

以上这几种情况都需要review代码来确认是否有相关流程,这部分流程对ion来讲是无感的,ion无法review到这种情况。

6. GPU/GL track

进一步分析dumpsys meminfo中的GL mtrack信息
注意:在进行GPU memory比对测试的时候需要先对齐以下几项

1. adb shell wm size
2. adb shell wm density (此数据需要在设定wm size后重启再查看)
3. adb shell "dumpsys SurfaceFlinger | grep refresh-rate" 

查看整机gpu memory用量

adb shell cat /proc/mtk_mali/gpu_memory
查看用量较大的PID, 如下图所示,中间列的数据是gpu_memory,实际size 需* 4k,  右边列为pid。

如GPU部分存在差异需要进一步厘清。

因篇幅问题不能全部显示,请点此查看更多更全内容

Top