Memory 概要
文摘 MediaTek 2020-03-24 阅读:13857系统memory 可简单分成以下几类
- user space memory
- anon (process memory , stack , heap ,..)
- file (file cache)
- swap (zipped anon)
- kernel space memory
- slab_reclaimable
- slab_unreclaimable
- kernel_stack
- ion (mutimedia/camera)
- gpu (display/graphic)
查看内存分布
- adb cat /proc/meminfo
- MemTotal: 1876772 kB //系统可用的总内存 (MemTotal = real_Dram_size - hw_reserved - kernel_reserved )
- MemFree: 46304 kB //系统剩余尚未使用的内存
- MemAvailable: 424492 kB //系统可用内存 , 包含已使用但可回收的 , 如cache/buffer、slab一部分
- Buffers: 6988 kB //用于文件缓冲
- Cached: 393952 kB //用于文件高速缓存,约等于 Active(file) + Inactive(file)
- SwapCached: 5312 kB //用于swap缓存
- Active: 446960 kB //活跃使用状态,记录最近使用过的内存,通常不回收用于其它目的
- Inactive: 454008 kB //非活跃使用状态,记录最近并没有使用过的内存,能够被回收用于其他目的
- Active(anon): 249988 kB //Active = Active(anon) + Active(file)
- Inactive(anon): 255448 kB //Inactive = Inactive(anon) + Inactive(file)
- Active(file): 196972 kB
- Inactive(file): 198560 kB
- Unevictable: 5580 kB
- Mlocked: 5580 kB
- SwapTotal: 1048572 kB //swap总大小
- SwapFree: 57300 kB //swap可用大小
- Dirty: 164 kB //等待往磁盘回写的大小
- Writeback: 0 kB //正在往磁盘回写的大小
- AnonPages: 504068 kB //匿名页,用户空间的页表,没有对应的文件
- Mapped: 305784 kB //文件通过mmap分配的内存,用于map设备、文件或者库
- Shmem: 516 kB
- Slab: 194932 kB //kernel数据结构的缓存大小,Slab=SReclaimable+SUnreclaim
- SReclaimable: 39936 kB //可回收的slab的大小
- SUnreclaim: 154996 kB //不可回收slab的大小
- KernelStack: 69840 kB
- PageTables: 99908 kB //以最低的页表级
- NFS_Unstable: 0 kB //不稳定页表的大小
- Bounce: 0 kB
- WritebackTmp: 0 kB
- CommitLimit: 1986956 kB
- Committed_AS: 134795476 kB
- VmallocTotal: 263061440 kB //总分配的虚拟地址空间
- VmallocUsed: 0 kB //已使用的虚拟地址空间
- VmallocChunk: 0 kB //虚拟地址空间可用的最大连续内存块
- CmaTotal: 0 kB
- CmaFree: 0 kB
内存分布log 查看方式
kernel log
<4>[366310.867958] DMA free:68160kB min:5140kB low:44156kB high:45996kB active_anon:126592kB inactive_anon:126772kB active_file:211508kB inactive_file:185592kB unevictable:5380kB writepending:1896kB present:1988536kB managed:1841596kB mlocked:5380kB slab_reclaimable:40648kB slab_unreclaimable:187980kB kernel_stack:49760kB pagetables:78368kB bounce:0kB free_pcp:2844kB local_pcp:696kB free_cma:0kB
- DMA free:68160kB
- 总剩余内存
- min:5140kB low:44156kB high:45996kB
- min/low/high 三个水位值
- active_anon:126592kB inactive_anon:126772kB
- userspace process memory
- active_file:211508kB inactive_file:185592kB
- userspace file cache memory
- managed:1841596kB
- dram total减掉 reserved memory ,系统总共可运用的内存大小
- slab_reclaimable:40648kB slab_unreclaimable:187980kB
- slab 占用内存
- kernel_stack:49760kB
- kernel stack 占用内存, 可用来计算process数量 (32bit 8k per process , 64bit 16k per porcess)
- 注意ion 和 gpu 无法由此看出
lowmemory killer log查看方式
<4>[366675.752164] (5)[138:kswapd0:0]3038 pages in swap cache
<4>[366675.752181] (5)[138:kswapd0:0]Swap cache stats: add 901120852, delete 901117814, find 143707351/518237855
<4>[366675.752186] (5)[138:kswapd0:0]Free swap = 6700kB //剩余swap 大小
<4>[366675.752191] (5)[138:kswapd0:0]Total swap = 1310716kB //总swap分区大小
<4>[366675.752197] (5)[138:kswapd0:0]497134 pages RAM
<4>[366675.752201] (5)[138:kswapd0:0]0 pages HighMem/MovableOnly
<4>[366675.752207] (5)[138:kswapd0:0]36735 pages reserved
<4>[366675.752224] (5)[138:kswapd0:0]0 pages cma reserved
<4>[366675.752229] (5)[138:kswapd0:0]19548 pages ion total used
<6>[366675.770473] (3)[139:kswapd0:1]lowmemorykiller: Killing '.player:service' (12457) (tgid 12457), adj 800,
<6>[366675.770473] to free 19796kB on behalf of 'kswapd0:1' (139) because
<6>[366675.770473] cache 190580kB is below limit 294912kB for oom_score_adj 300 (300)
<6>[366675.770473] Free memory is 4396kB above reserved(decrease 2 level)
- lowmemorykiller log 说明
- 由kswapd0 进程进行内存回收时触发lowmemory killer机制杀进程
- .player:service 为被杀进程 , 对应 pid=12457 , tid=12457 , adj=800
- 释放 19796 KB 内存
- decrease 2 level 表示mtk AMR (aggressive memory relaim 机制,根据swap free/swap total , <1/2 降 1 , <1/4 降2) , 当下swap <1/4 所以降 2 level
- 当下cache大小 190580kB 低于 294912kB , oom adj =906 -> 900 -> 300 (降2 level)
- oom adj 参考/sys/module/lowmemorykiller/parameters/adj
- oom minfree 参考/sys/module/lowmemorykiller/parameters/minfree
基本debug指令
查看系统memory 使用情况
- adb shell cat /proc/meminfo
- adb shell dumpsys meminfo
- adb shell procrank
查看单一进程memory 使用情况
- adb shell dumpsys meminfo $pid
- adb shell procmem $pid
查看系统memory 走势与各进程使用情形
- adb shell cat /d/mlog (预设每秒更新一次)
- mlog 格式如下
- type 表示触发mlog的原因,0表示是timer触发,1表示是LMK,2表示LTK
- [time] 当前的kernel 时间
- memfr 空闲的memory
- swpfr swap区域的free量
- cache 缓存占用的memory的量
- kernel_stack 内核栈用的量
- page_table page table占用的量
- slab slab区域使用的memory
- gpu gpu使用的memory
- gpu_page_cache gpu部分缓存用的量
- zram zram区域的mwmory 总量
- active active区域的mwmory 总量
- inactive inactive区域的mwmory 总量
- shmem shmem区域的mwmory 总量
- ion ion区域的mwmory 总量
- swpin 换入的次数
- swpout 换出的次数
- fmflt 系统发生file page fault的次数
- [normal: 0 normal 区域buddy的情况
- [high: 0 high区域的buddy情况
- [pid] 进程PID
- adj adj值
- rss 使用内存
- rswp 使用内存 in swap分区的部分
- pswpin 进程的文件发生的换入次数
- pswpout 进程的文件发生的换出次数
- pfmlt 进程PID文件缺页异常发生的次数
查看swap(zram)分区使用情况
- cat /proc/zraminfo
查看ion memory 使用情况
- adb cat /d/ion/ion_mm_heap
- adb cat /d/ion/client_history
查看gpu memory 使用情况
- IMG
- cat /d/pvr/driver_stats
- cat /d/pvr/memtrack_stats
- cat /d/pvr/pid/apk_pid/process_stats
- cat /d/pvr/pid/apk_pid/mem_area
- Mali
- cat /d/mali0/gpu_memory
- cat /d/mali0/memory_usage
- cat /d/mali0/ctx
查看 slab 使用情况
- FAQ21613 [Memory] 如何分析slab占用内存细节以及slab leak
查看 page 使用情况
- adb shell cat /proc/zoneinfo
- adb shell cat /proc/buddyinfo
- FAQ21615 [Memory]如何查询内核所有 page 的使用情况 (by page owner)
查看reserved memory
- adb shell cat /proc/mtk_memcfg/total_reserve //总reserved memory 大小
- adb shell cat /proc/mtk_memcfg/reserve_memory //reserved memory 条列
- adb shell echo 0 > /proc/sys/kernel/kptr_restrict
- adb shell cat /proc/mtk_memcfg/memory_layout //reserved memory 分布
LMKD 参数
Parameter | Description | Defaultvalue | LowRamvalue |
---|---|---|---|
ro.lmk.debug | debug 开关, 除了killing log以外的debug 讯息需要打开这个才能看的到 | false | |
ro.lmk.kill_heaviest_task | kill process 从最大占用内存process 开始kill | false | |
ro.config.low_ram | 一般ago device定义为low ram device , 目前是1GB ram 以下的device , 有两个特点 1.依据不同oomadj 限制内存 , 2.一次只会kill 一个process | false | |
ro.lmk.kill_timeout_ms | kill process 后下次kill 中间间隔的 timeout 时间 | 0 | |
ro.lmk.use_minfree_levels | 采用kernel lowmemory killer 的 cache /minfree 参考机制来kill process , 而非参考memory pressure | false | |
Mem Pressure relative | |||
ro.lmk.low | memory pressure 为low 时kill 的最低 adj | 1001 | |
ro.lmk.medium | memory pressure 为medium时kill 的最低 adj | 800 | |
ro.lmk.critical | memory pressure 为high时kill 的最低 adj | 0 | |
ro.lmk.critical_upgrade | 允许 memory pressure 从medium 被上升到critical ,条件是mem_pressure计算低于upgrade_pressure临界值 | false | |
ro.lmk.upgrade_pressure | critical pressure 的参考值 , 以上为medium ,以下为critical | 100 | |
ro.lmk.downgrade_pressure | medium pressure 的参考值 , 以上为low ,以下为medium | 100 | |
PSI relative (>=AndroidQ) | |||
ro.lmk.use_psi | kernel 使用psi event上发lmkd | 1 | 1 |
ro.lmk.use_new_strategy | 1: use mp_event_psi , 0: use mp_event_common to kill process | 0 | 1 |
ro.lmk.swap_free_low_percentage | 判定swap low的百分比 ex : swap free < 10/100 | 20 | 10 |
ro.lmk.thrashing_limit | 判定 thrashing 的标准值 | 100 | 30 |
ro.lmk.thrashing_limit_decay | thrashing limit衰减百分比 , 每次衰减 thrashing_limit = (thrashing_limit * (100 - thrashing_limit_decay_pct)) / 100 | 10 | 50 |
ro.lmk.psi_partial_stall_ms | partial PSI stall threshold in milliseconds for triggering low memory notification. Default for low-RAM devices = 200, for high-end devices = 70 (PSI_SOME) | 70 | 200 |
ro.lmk.psi_complete_stall_ms | complete PSI stall threshold in milliseconds for triggering critical memory notification. Default =700 (PSI_FULL) | 700 | 700 |
ro.lmk.thrashing_min_score_adj | f发生thrashing 时kill 的 min score adj | 200 | 200 |
/proc/sys/vm 参数
- admin_reserve_kbytes
- The amount of free memory in the system that should be reserved for users
with the capability cap_sys_admin. - block_dump
- block_dump enables block I/O debugging when set to a nonzero value.
- compact_memory
- Available only when CONFIG_COMPACTION is set. When 1 is written to the file,
all zones are compacted such that free memory is available in contiguous
blocks where possible. - compact_unevictable_allowed
- Available only when CONFIG_COMPACTION is set. When set to 1, compaction is
allowed to examine the unevictable lru (mlocked pages) for pages to compact. - dirty_background_bytes
- Contains the amount of dirty memory at which the background kernel
flusher threads will start writeback. - dirty_background_ratio
- Contains, as a percentage of total available memory that contains free pages
and reclaimable pages, the number of pages at which the background kernel
flusher threads will start writing out dirty data. - dirty_bytes
- Contains the amount of dirty memory at which a process generating disk writes
will itself start writeback. - dirty_expire_centisecs
- This tunable is used to define when dirty data is old enough to be eligible
for writeout by the kernel flusher threads. - dirty_ratio
- Contains, as a percentage of total available memory that contains free pages
and reclaimable pages, the number of pages at which a process which is
generating disk writes will itself start writing out dirty data. - dirty_writeback_centisecs
- The kernel flusher threads will periodically wake up and write `old' data
out to disk. - drop_caches
- Writing to this will cause the kernel to drop clean caches, as well as
reclaimable slab objects like dentries and inodes. Once dropped, their
memory becomes free. - echo 1 to free pagecache
- echo 2 to free reclaimable slab objects (includes dentries and inodes)
- echo 3 to slab objects and pagecache
- extfrag_threshold
- This parameter affects whether the kernel will compact memory or direct
reclaim to satisfy a high-order allocation. - extra_free_kbytes
- This parameter tells the VM to keep extra free memory between the threshold
where background reclaim (kswapd) kicks in, and the threshold where direct
reclaim (by allocating processes) kicks in. - hugepages_treat_as_movable
- This parameter controls whether we can allocate hugepages from ZONE_MOVABLE
or not. - hugetlb_shm_group
- hugetlb_shm_group contains group id that is allowed to create SysV
shared memory segment using hugetlb page. - laptop_mode
- laptop_mode is a knob that controls "laptop mode".
- legacy_va_layout
- If non-zero, this sysctl disables the new 32-bit mmap layout - the kernel
will use the legacy (2.4) layout for all processes. - lowmem_reserve_ratio
- The `lowmem_reserve_ratio' tunable determines how aggressive the kernel is
in defending these lower zones. - max_map_count
- This file contains the maximum number of memory map areas a process
may have. - memory_failure_early_kill
- Control how to kill processes when uncorrected memory error (typically
a 2bit error in a memory module) is detected in the background by hardware
that cannot be handled by the kernel. - memory_failure_recovery
- Enable memory failure recovery (when supported by the platform)
- 1: Attempt recovery.
- 0: Always panic on a memory failure.
- min_free_kbytes
- This is used to force the Linux VM to keep a minimum number
of kilobytes free. The VM uses this number to compute a
watermark[WMARK_MIN] value for each lowmem zone in the system. - min_slab_ratio
- This is available only on NUMA kernels.
- min_unmapped_ratio
- This is available only on NUMA kernels.
- mmap_min_addr
- This file indicates the amount of address space which a user process will
be restricted from mmapping. - mmap_rnd_bits
- This value can be used to select the number of bits to use to
determine the random offset to the base address of vma regions
resulting from mmap allocations on architectures which support
tuning address space randomization. - mmap_rnd_compat_bits
- This value can be used to select the number of bits to use to
determine the random offset to the base address of vma regions
resulting from mmap allocations for applications run in
compatibility mode on architectures which support tuning address
space randomization. - nr_hugepages
- Change the minimum size of the hugepage pool.
- nr_overcommit_hugepages
- Change the maximum size of the hugepage pool. The maximum is
nr_hugepages + nr_overcommit_hugepages. - nr_trim_pages (only if CONFIG_MMU=n)
- This is available only on NOMMU kernels.
- numa_zonelist_order
- This sysctl is only for NUMA.
- oom_dump_tasks
- Enables a system-wide task dump (excluding kernel threads) to be produced
when the kernel performs an OOM-killing and includes such information as
pid, uid, tgid, vm size, rss, nr_ptes, nr_pmds, swapents, oom_score_adj
score, and name. - oom_kill_allocating_task
- This enables or disables killing the OOM-triggering task in
out-of-memory situations. - overcommit_kbytes
- When overcommit_memory is set to 2, the committed address space is not
permitted to exceed swap plus this amount of physical RAM. - overcommit_memory
- This value contains a flag that enables memory overcommitment.
- 0: the kernel attempts to estimate the amount
of free memory left when userspace requests more memory. - 1: the kernel pretends there is always enough
memory until it actually runs out. - 2: the kernel uses a "never overcommit" policy that attempts to prevent any overcommit of memory. Note that user_reserve_kbytes affects this policy.
- overcommit_ratio
- When overcommit_memory is set to 2, the committed address
space is not permitted to exceed swap plus this percentage
of physical RAM. - page-cluster
- page-cluster controls the number of pages up to which consecutive pages
are read in from swap in a single attempt. This is the swap counterpart
to page cache readahead. - panic_on_oom
- This enables or disables panic on out-of-memory feature.
- percpu_pagelist_fraction
- This is the fraction of pages at most (high mark pcp->high) in each zone that
are allocated for each per cpu page list. - stat_interval
- The time interval between which vm statistics are updated. The default
is 1 second. - stat_refresh
- Any read or write (by root only) flushes all the per-cpu vm statistics
into their global totals, for more accurate reports when testing
e.g. cat /proc/sys/vm/stat_refresh /proc/meminfo - swappiness
- This control is used to define how aggressive the kernel will swap
memory pages. - The default value is 60.
- user_reserve_kbytes
- When overcommit_memory is set to 2, "never overcommit" mode, reserve
min(3% of current process size, user_reserve_kbytes) of free memory. - vfs_cache_pressure
- This percentage value controls the tendency of the kernel to reclaim
the memory which is used for caching of directory and inode objects. - watermark_scale_factor
- This factor controls the aggressiveness of kswapd. It defines the
amount of memory left in a node/system before kswapd is woken up and
how much memory needs to be free before kswapd goes back to sleep.