先放总结:对于系统的tmpfs,其为共享内存分配,对其的使用,尽量当缓存使用,使用完后及时删除,尽量存储小文件。
背景:
出现卡屏后,第一时间通常是:dumpsys meminfo
[11:29:22]Total RAM: 3,596,420K (status critical)
[11:29:22] Free RAM: 2,022,660K ( 0K cached pss + 1,890,164K cached kernel + 132,496K free)
[11:29:22] Used RAM: 3,580,421K (1,034,693K used pss + 2,545,728K kernel)
[11:29:22] Lost RAM: -2,006,661K
[11:29:22] Tuning: 192 (large 512), oom 322,560K, restore limit 107,520K (high-end-gfx)
发现kernel占用了约2.5G,哇,吓人。
分析:
1、实际上dumpsys meminfo中 Used RAM下的kernel部分的大小: Shmem + SUnreclaim + VmallocUsed + PageTables + KernelStack。 但是这部分的统计比实际占用要多,主要在VmallocUsed的统计。
更多dumpsys meminfo的信息可以查看此链接:
2、查看/proc/meminfo
[11:39:06]cat /proc/meminfo
[11:39:06]MemTotal: 3596420 kB
[11:39:06]MemFree: 136140 kB
[11:39:06]MemAvailable: 127308 kB
[11:39:06]Buffers: 1836 kB
[11:39:06]Cached: 1870864 kB
[11:39:06]SwapCached: 0 kB
[11:39:06]Active: 914900 kB
[11:39:06]Inactive: 1833160 kB
[11:39:06]Active(anon): 875804 kB
[11:39:06]Inactive(anon): 1800380 kB
[11:39:06]Active(file): 39096 kB
[11:39:06]Inactive(file): 32780 kB
[11:39:06]Unevictable: 256 kB
[11:39:06]Mlocked: 256 kB
[11:39:06]SwapTotal: 0 kB
[11:39:06]SwapFree: 0 kB
[11:39:06]Dirty: 228 kB
[11:39:06]Writeback: 0 kB
[11:39:06]AnonPages: 875616 kB
[11:39:06]Mapped: 61016 kB
[11:39:06]Shmem: 1800812 kB
[11:39:06]Slab: 233588 kB
[11:39:06]SReclaimable: 80352 kB
[11:39:06]SUnreclaim: 153236 kB
[11:39:06]KernelStack: 24672 kB
[11:39:06]PageTables: 32432 kB
[11:39:06]NFS_Unstable: 0 kB
[11:39:06]Bounce: 0 kB
[11:39:06]WritebackTmp: 0 kB
[11:39:06]CommitLimit: 1798208 kB
[11:39:06]Committed_AS: 90198500 kB
[11:39:06]VmallocTotal: 135290290112 kB
[11:39:06]VmallocUsed: 0 kB
[11:39:06]VmallocChunk: 0 kB
[11:39:06]AnonHugePages: 288768 kB
[11:39:06]ShmemHugePages: 0 kB
[11:39:06]ShmemPmdMapped: 0 kB
[11:39:06]CmaTotal: 671744 kB
[11:39:06]CmaFree: 58136 kB
[11:39:06]HugePages_Total: 0
[11:39:06]HugePages_Free: 0
[11:39:06]HugePages_Rsvd: 0
[11:39:06]HugePages_Surp: 0
[11:39:06]Hugepagesize: 2048 kB
上面的Shmem占用了1.8G,对比没问题时才几兆;slab通常是kernel的内存使用,异常时也才200+M;从这里发现并不kernel的内存泄漏。但是Shmem怎么会这么大呢,跟正常相比差异太大了,各种百度,都没有shmem过大的问题。
3、谷歌来了一句 Shmem so big
就简单提示了查看df,下面这份是正常的,tmpfs几乎没使用,当异常的时候其中/mnt会满,tmpfs是存储在共享内存中,所以当tmpfs使用越多,shmem就越大,直到不能使用。
127|g6sa:/ $ df -h
Filesystem Size Used Avail Use% Mounted on
/dev/root 1.7G 575M 1.1G 34% /
tmpfs 1.7G 548K 1.7G 1% /dev
/dev/block/dm-1 3.6G 1.3G 2.2G 38% /vendor
tmpfs 1.7G 0 1.7G 0% /mnt
/dev/block/mmcblk0p17 3.8M 748K 3.0M 20% /mcu
/dev/block/mmcblk0p19 4.3G 19M 4.2G 1% /data_fota
/dev/block/mmcblk0p22 41G 981M 39G 3% /data
/data/media 41G 981M 39G 3% /storage/emulated
4、继续查看为什么/mnt会占满,发现是/storage/usb1 占满了,但没有插U盘啊,怎么会有usb1呢,这个下面分析,先分析路径关系
/mnt与/storage的关系,可以通过mount查看
91797.21> g6sa:/ # mount | grep storage
91797.28> tmpfs on /storage type tmpfs (rw,seclabel,relatime,mode=755,gid=1000)
91797.29> /data/media on /storage/emulated type sdcardfs (rw,nosuid,nodev,noexec,noatime,fsuid=1023,fsgid=1023,gid=1015,multiuser,mask=6,derive_gid)
91797.29> /mnt/media_rw/usb0 on /storage/usb0 type sdcardfs (rw,nosuid,nodev,noexec,noatime,fsuid=1023,fsgid=1023,gid=1015,mask=6)
然后去/mnt/runtime/default查看
92001.81> g6sa:/mnt/runtime/default # ls
92001.84> emulated self usb0
去/storage查看
92064.28> g6sa:/storage # ls
92064.31> emulated self usb0
原来/storage是/mnt上的一个映射路径
5、为什么没有U盘却有/storage/usb1,这是log机制的一个bug,这里不分析
6、删除/storage/usb1文件夹后,发现内存回来了。