当前位置: 首页 > news >正文

谈谈网站建设会有哪些问题中国最新的军事新闻

谈谈网站建设会有哪些问题,中国最新的军事新闻,搜索企业信息的网站,wordpress页面上分页一、低内存终止守护程序 Android 低内存终止守护程序 (lmkd) 进程可监控运行中的 Android 系统的内存状态#xff0c;并通过终止最不必要的进程来应对内存压力大的问题#xff0c;使系统以可接受的性能水平运行。 所有应用进程都是从zygote孵化出来的#xff0c;记录在AMS… 一、低内存终止守护程序 Android 低内存终止守护程序 (lmkd) 进程可监控运行中的 Android 系统的内存状态并通过终止最不必要的进程来应对内存压力大的问题使系统以可接受的性能水平运行。 所有应用进程都是从zygote孵化出来的记录在AMS中mLruProcesses列表中由AMS进行统一管理AMS中会根据进程的状态更新进程对应的oom_adj值这个值会通过socket传递给lmkd。lmdk根据内核的版本情况或传递给kernel或自身处理低内存回收机制。为腾出更多的内存空间在内存达到一定阀值时会触发清理oom_adj值高的进程。 1. 内存压力简介 并行运行多个进程的 Android 系统可能会遇到系统内存耗尽需要更多内存的进程出现明显延迟的情况。内存压力是系统内存不足的一种状态它需要 Android 通过限制或终止不必要的进程、请求进程释放非关键缓存资源等方式来释放内存以缓解这种压力。 过去Android 使用内核中的低内存终止守护程序 (LMK) 驱动程序来监控系统内存压力该驱动程序是一种依赖于硬编码值的严格机制。从内核 4.12 开始LMK 驱动程序已从上游内核中移除改由用户空间 lmkd 来执行内存监控和进程终止任务。 2. 压力失速信息 Android 10 及更高版本支持新的 lmkd 模式它使用内核压力失速信息 (PSI) 监视器来检测内存压力。上游内核中的 PSI 补丁程序集已向后移植到 4.9 和 4.14 内核可测量由于内存不足导致任务延迟的时间。由于这些延迟会直接影响用户体验因此它们代表了确定内存压力严重性的便捷指标。上游内核还包括 PSI 监视器这类监视器允许特权用户空间进程例如 lmkd指定这些延迟的阈值并在突破阈值时从内核订阅事件。 ① PSI 监视器与 vmpressure 信号 由于 vmpressure 信号由内核生成用于检测内存压力并由 lmkd 使用通常包含大量误报因此 lmkd 必须执行过滤以确定是否真的存在内存压力。这会导致不必要的 lmkd 唤醒并使用额外的计算资源。使用 PSI 监视器可以实现更精确的内存压力检测并最大限度地减少过滤开销。 ②使用 PSI 监视器 如需使用 PSI 监视器而不是 vmpressure 事件请配置 ro.lmk.use_psi 属性。默认值为 true这会以 PSI 监视器作为 lmkd 内存压力检测的默认机制。由于 PSI 监视器需要内核支持因此内核必须包含 PSI 向后移植补丁程序并在启用 PSI 支持 (CONFIG_PSIy) 的情况下进行编译。 3. 内核中 LMK 驱动程序的缺点 由于存在大量问题Android 弃用了 LMK 驱动程序问题包括 对于低内存设备必须主动进行调整即便如此在处理涉及支持大文件的活跃页面缓存的工作负载时其性能也较差。性能不良会导致出现抖动但不会终止。LMK 内核驱动程序依赖于可用内存限制不会根据内存压力进行扩缩。由于设计的严格性合作伙伴通常会自定义该驱动程序使其可以在自己的设备上使用。LMK 驱动程序已挂接到 Slab Shrinker API该 API 并非为了执行繁重操作例如搜索并终止目标而设计这类操作会导致 vmscan 进程变慢。 4. 用户空间 lmkd 用户空间 lmkd 可实现与内核中的驱动程序相同的功能但它使用现有的内核机制检测和评估内存压力。这些机制包括使用内核生成的 vmpressure 事件或压力失速信息 (PSI) 监视器来获取关于内存压力水平的通知以及使用内存 cgroup 功能限制根据进程的重要性分配给每个进程的内存资源。 在 Android 10 中使用用户空间 lmkd 在 Android 9 及更高版本中用户空间 lmkd 会在未检测到内核中的 LMK 驱动程序时激活。由于用户空间 lmkd 要求内核支持内存 cgroup因此必须使用以下配置设置编译内核 CONFIG_ANDROID_LOW_MEMORY_KILLERn CONFIG_MEMCGy CONFIG_MEMCG_SWAPy 终止策略 用户空间 lmkd 支持基于以下各项的终止策略vmpressure 事件或 PSI 监视器、其严重性以及交换利用率等其他提示。低内存设备和高性能设备的终止策略有所不同 对于内存不足的设备一般情况下系统会选择承受较大的内存压力。对于高性能设备如果出现内存压力则会视为异常情况应及时修复以免影响整体性能。 您可以使用 ro.config.low_ram 属性配置终止策略。如需了解详情请参阅低 RAM 配置。 用户空间 lmkd 还支持一种旧模式在该模式下它使用与内核中的 LMK 驱动程序相同的策略即可用内存和文件缓存阈值做出终止决策。要启用旧模式请将 ro.lmk.use_minfree_levels 属性设置为 true。 5. 图解 5-1. LMK/LMKD 5-2. lmkd kill process flow lmkd can use minfree table to adjust which adj process to kill (ro.lmk.use_minfree_levels1) or use medium/critical pressure to adjust which adj process to kill (ro.lmk.use_minfree_levels0). the midum/citical pressure adjust was configured by ro.lmk.medium/ro.lmk.critical , which default value was 800/0 . lmkd log:(in main log) ro.lmk.use_minfree_levels1 ro.lmk.use_minfree_levels0 5-3. lmk kill process flow lmk log: (in kernel log) 6 .minfree table oom adj 6.1 minfree table adb shell cat /sys/module/lowmemorykiller/parameters/minfree 或者 adb root adb shell getprop |grep minfree [sys.lmk.minfree_levels]: [18432:0,23040:100,27648:200,32256:250,36864:900,46080:950] 6.2 如何修改? •可以通过修改修改minfree表 (frameworks/base/core/res/res/values/config.xml) config_lowMemoryKillerMinFreeKbytesAbsolute config_lowMemoryKillerMinFreeKbytesAdjust (frameworks/base/services/core/java/com/android/server/am/ProcessList.java) updateOomLevels() functions calculation formula or default value table(mOomMinFreeLow/mOomMinFreeHigh) 6.3 oom adj ADJ优先级 OOMADJ 对应场景 UNKNOWN_ADJ 1001 一般指将要会缓存进程无法获取确定值 CACHED_APP_MAX_ADJ 906 不可见进程的adj最大值不可见进程可能在任何时候被杀死 CACHED_APP_MIN_ADJ 900 不可见进程的adj最小值不可见进程可能在任何时候被杀死 SERVICE_B_ADJ 800 B List中的Service较老的、使用可能性更小 PREVIOUS_APP_ADJ 700 上一个App的进程(比如APP_A跳转APP_B,APP_A不可见的时候A就是属于PREVIOUS_APP_ADJ) HOME_APP_ADJ 600 Home进程 SERVICE_ADJ 500 服务进程(Service process) HEAVY_WEIGHT_APP_ADJ 400 后台的重量级进程system/rootdir/init.rc文件中设置 BACKUP_APP_ADJ 300 备份进程 PERCEPTIBLE_APP_ADJ 200 可感知进程比如后台音乐播放 VISIBLE_APP_ADJ 100 可见进程(可见但是没能获取焦点比如新进程仅有一个悬浮ActivityVisible process) FOREGROUND_APP_ADJ 0 前台进程正在展示是APP存在交互界面Foreground process PERSISTENT_SERVICE_ADJ -700 关联着系统或persistent进程 PERSISTENT_PROC_ADJ -800 系统persistent进程比如telephony SYSTEM_ADJ -900 系统进程 NATIVE_ADJ -1000 native进程不被系统管理 7. lmkd parameters Parameter Description Defaultvalue LowRamvalue ro.lmk.debug debug 开关 除了killing log以外的debug 讯息需要打开这个才能看的到 false ro.lmk.kill_heaviest_task 默认false - 每次需要杀进程时则从高oom_adj开始遍历同oom_adj时从最后加入列表的开始杀直到释放出足够内存为止 true - 每次需要杀进程时则从高oom_adj开始遍历同oom_adj时从rss最高的进程开始杀参考节点/proc/$pid/statm中的第二个数值直到释放出足够内存为止 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 mp_event_common 使用的prop和PSI 参数不同时生效 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) mp_event_psi使用的参数和Pressuure参数不同时生效 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.swap_util_max 最大内存交换量占可交换内存的百分比。(默认值实际上会停用此功能) 100 100 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 内存失速阈值。用于触发内存不足的通知。 Default for low-RAM devices 200, for high-end devices 70 PSI_SOME 70 200 ro.lmk.psi_complete_stall_ms 完全PSI失速阈值。用于触发关键内存通知。 Default 700 PSI_FULL 700 700 ro.lmk.thrashing_min_score_adj 发生thrashing 时kill 的 min score adj 200 200 二、低内存的数据特征和行为特征 1、Meminfo 信息 最简单的方法是使用 Android 系统自带的 Dumpsys meminfo 工具 1 2 3 4 5 6 7 8 adb shell dumpsys meminfo ...... Total RAM: 7,658,060K (status moderate) Free RAM: 550,200K ( 78,760K cached pss 156,ba480K cached kernel 314,960K free) Used RAM: 7,718,091K (6,118,703K used pss 1,599,388K kernel) Lost RAM: -319,863K ZRAM: 2,608K physical used for 301,256K in swap (4,247,544K total swap) Tuning: 256 (large 512), oom 322,560K, restore limit 107,520K (high-end-gfx) 如果系统处于低内存的话 , 会有如下特征: FreeRam 的值非常少 , Used RAM 的值非常大ZRAM 使用率非常高如果开了 Zram 的话 2、LMK kswapd 线程活跃 低内存的时候 LKMD 会非常活跃 在 Kernel Log 里面可以看到 LMK 杀进程的信息: 1 2 3 4 5 6 7 8 9 [kswapd0] lowmemorykiller: Killing u.mzsyncservice (15609) (tgid 15609), adj 906, to free 28864kB on behalf of kswapd0 (91) because cache 258652kB is below limit 261272kB for oom score 906 Free memory is -5540kB above reserved. Free CMA is 3172kB Total reserve is 227288kB Total free pages is 271748kB Total file cache is 345384kB GFP mask is 0x14000c0 上面这段 Log 的意思是说 由于 mem 低于我们设定的 900 的水位线 261272kB所以把 pid 为 15609 的 mzsyncservice 这个进程杀掉这个进程的 adj 是 906 3、proc/meminfo 这里是 Linux Kernel 展示 meminfo 的地方 , 关于 meminfo 的解读可以参考这篇文章/PROC/MEMINFO之谜 从结果来 , 当系统处于低内存的情况时候 , MemFree 和 MemAvailable 的值都很小 shell cat proc/meminfo 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 MemTotal: 5630104 kB MemFree: 148928 kB MemAvailable: 864172 kB Buffers: 28464 kB Cached: 1003144 kB SwapCached: 19844 kB Active: 1607512 kB Inactive: 969208 kB Active(anon): 1187828 kB Inactive(anon): 426192 kB Active(file): 419684 kB Inactive(file): 543016 kB Unevictable: 62152 kB Mlocked: 62152 kB SwapTotal: 2097148 kB SwapFree: 42576 kB Dirty: 3604 kB Writeback: 0 kB AnonPages: 1602928 kB Mapped: 996768 kB Shmem: 7284 kB Slab: 306440 kB SReclaimable: 72320 kB SUnreclaim: 234120 kB KernelStack: 89776 kB PageTables: 107572 kB NFS_Unstable: 0 kB Bounce: 0 kB WritebackTmp: 0 kB CommitLimit: 4912200 kB Committed_AS: 118487976 kB VmallocTotal: 263061440 kB VmallocUsed: 0 kB VmallocChunk: 0 kB CmaTotal: 303104 kB CmaFree: 3924 kB 4、整机卡顿 响应慢 低内存的时候整机使用的时候要比非低内存的时候要卡很多点击应用或者启动 App 都会有不顺畅或者响应慢的感觉 三、低内存对性能的具体影响 1、LMK 频繁工作抢占 cpu LMK 工作时, 会占用 cpu 资源 , 其表现主要有下面几点 CPU 资源 : 由于 LMK 杀掉的进程通常都是一些 Cache 或者 Service , 这些进程由于低内存被杀之后 , 通常会很快就被其主进程拉起来, 然后又被 LMK 杀掉, 从而进入了一种循环. 由于起进程是一件很消耗 cpu 的操作, 所以如果后台一直有进程被杀和重启, 那么前台的进程很容易出现卡顿Memory : 由于低内存的原因, 很容易触发各个进程的 GC , 如下图的 CPU 状态可以看到, 用于内存回收的 HeapTaskDeamon 出现非常频繁IO : 低内存会导致磁盘 IO 变多, 如果频繁进行磁盘 IO , 由于磁盘IO 很慢, 那么主线程会有很多进程处于等 IO 的状态, 也就是我们经常看到的 Uninterruptible Sleep2、影响主线程 IO 操作 主线程出现大量的 IO 相关的问题 反馈到 Trace 上就是有大量的黄色 Trace State 出现 , 例如 : Uninterruptible Sleep | WakeKill - Block I/O .查看其 Block 信息 kernel callsite when blocked:: “wait_on_page_bit_killable0x78/0x88 Linux 系统的 page cache 链表中有时会出现一些还没准备好的 page ( 即还没把磁盘中的内容完全地读出来 ) , 而正好此时用户在访问这个 page 时就会出现 wait_on_page_locked_killable 阻塞了. 只有系统当 io 操作很繁忙时, 每笔的 io 操作都需要等待排队时, 极其容易出现且阻塞的时间往往会比较长. 当出现大量的 IO 操作的时候应用主线程的 Uninterruptible Sleep 也会变多此时涉及到 io 操作比如 view 读文件读配置文件、读 odex 文件都会触发 Uninterruptible Sleep 导致整个操作的时间变长 3、出现 CPU 竞争 低内存会触发 Low Memory Killer 进程频繁进行扫描和杀进程kswapd0 是一个内核工作线程内存不足时会被唤醒做内存回收的工作。 当内存频繁在低水位的时候kswapd0 会被频繁唤醒占用 cpu 造成卡顿和耗电。 比如下面这个情况 kswapd0 占用了 855 的超大核 cpu7 而且是满频在跑耗电可想而知如果此时前台应用的主线程跑到了 cpu7 上很大可能会出现 cpu 竞争导致调度不到而丢帧。 HeapTaskDaemon 通常也会在低内存的时候跑的很高 , 来做内存相关的操作 4、进程频繁查杀和重启 对 AMS 的影响主要集中在进程的查杀上面 , 由于 LMK 的介入 , 处于 Cache 状态的进程很容易被杀掉 , 然后又被他们的父进程或者其他的应用所拉起来 , 导致陷入了一种死循环 . 对系统 CPU \ Memory \ IO 等资源的影响非常大. 比如下面就是一次 Monkey 之后的结果 , QQ 在短时间内频繁被杀和重启 . 14:32:16.932 1435 1510 I am_proc_start: [0,30387,10145,com.tencent.mobileqq,restart,com.tencent.mobileqq] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 07-23 14:32:16.969 1435 3420 I am_proc_bound: [0,30387,com.tencent.mobileqq] 07-23 14:32:16.979 1435 3420 I am_kill : [0,30387,com.tencent.mobileqq,901,empty #3] 07-23 14:32:16.996 1435 3420 I am_proc_died: [0,30387,com.tencent.mobileqq,901,18] 07-23 14:32:17.028 1435 1510 I am_proc_start: [0,30400,10145,com.tencent.mobileqq,restart,com.tencent.mobileqq] 07-23 14:32:17.054 1435 3420 I am_proc_bound: [0,30400,com.tencent.mobileqq] 07-23 14:32:17.064 1435 3420 I am_kill : [0,30400,com.tencent.mobileqq,901,empty #3] 07-23 14:32:17.082 1435 3420 I am_proc_died: [0,30400,com.tencent.mobileqq,901,18] 07-23 14:32:17.114 1435 1510 I am_proc_start: [0,30413,10145,com.tencent.mobileqq,restart,com.tencent.mobileqq] 07-23 14:32:17.139 1435 3420 I am_proc_bound: [0,30413,com.tencent.mobileqq] 07-23 14:32:17.149 1435 3420 I am_kill : [0,30413,com.tencent.mobileqq,901,empty #3] 07-23 14:32:17.166 1435 3420 I am_proc_died: [0,30413,com.tencent.mobileqq,901,18] 07-23 14:32:17.202 1435 1510 I am_proc_start: [0,30427,10145,com.tencent.mobileqq,restart,com.tencent.mobileqq] 07-23 14:32:17.216 1435 3420 I am_proc_bound: [0,30427,com.tencent.mobileqq] 07-23 14:32:17.226 1435 3420 I am_kill : [0,30427,com.tencent.mobileqq,901,empty #3] 07-23 14:32:17.249 1435 3420 I am_proc_died: [0,30427,com.tencent.mobileqq,901,18] 07-23 14:32:17.278 1435 1510 I am_proc_start: [0,30440,10145,com.tencent.mobileqq,restart,com.tencent.mobileqq] 07-23 14:32:17.299 1435 3420 I am_proc_bound: [0,30440,com.tencent.mobileqq] 07-23 14:32:17.309 1435 3420 I am_kill : [0,30440,com.tencent.mobileqq,901,empty #3] 07-23 14:32:17.329 1435 2116 I am_proc_died: [0,30440,com.tencent.mobileqq,901,18] 07-23 14:32:17.362 1435 1510 I am_proc_start: [0,30453,10145,com.tencent.mobileqq,restart,com.tencent.mobileqq] 07-23 14:32:17.387 1435 2116 I am_proc_bound: [0,30453,com.tencent.mobileqq] 07-23 14:32:17.398 1435 2116 I am_kill : [0,30453,com.tencent.mobileqq,901,empty #3] 07-23 14:32:17.420 1435 2116 I am_proc_died: [0,30453,com.tencent.mobileqq,901,18] 07-23 14:32:17.447 1435 1510 I am_proc_start: [0,30466,10145,com.tencent.mobileqq,restart,com.tencent.mobileqq] 07-23 14:32:17.474 1435 2116 I am_proc_bound: [0,30466,com.tencent.mobileqq] 07-23 14:32:17.484 1435 2116 I am_kill : [0,30466,com.tencent.mobileqq,901,empty #3] 07-23 14:32:17.507 1435 2116 I am_proc_died: [0,30466,com.tencent.mobileqq,901,18] 07-23 14:32:17.533 1435 1510 I am_proc_start: [0,30479,10145,com.tencent.mobileqq,restart,com.tencent.mobileqq] 07-23 14:32:17.556 1435 2116 I am_proc_bound: [0,30479,com.tencent.mobileqq] 07-23 14:32:17.566 1435 2116 I am_kill : [0,30479,com.tencent.mobileqq,901,empty #3] 07-23 14:32:17.587 1435 2116 I am_proc_died: [0,30479,com.tencent.mobileqq,901,18] 07-23 14:32:17.613 1435 1510 I am_proc_start: [0,30492,10145,com.tencent.mobileqq,restart,com.tencent.mobileqq] 07-23 14:32:17.636 1435 2116 I am_proc_bound: [0,30492,com.tencent.mobileqq] 07-23 14:32:17.646 1435 2116 I am_kill : [0,30492,com.tencent.mobileqq,901,empty #3] 07-23 14:32:17.667 1435 2116 I am_proc_died: [0,30492,com.tencent.mobileqq,901,18] 其对应的 Systrace - SystemServer 中可以看到 AM 在频繁杀 QQ 和起 QQ 此 Trace 对应的 Kernel 部分也可以看到繁忙的 cpu 5、影响内存分配和触发 IO 手机经过长时间老化使用整机卡顿一下 , 或者整体比刚刚开机的时候操作要慢 , 可能是因为触发了内存回收或者 block io , 而这两者又经常有关联 . 内存回收可能触发了 fast path 回收 \ kswapd 回收 \ direct reclaim 回收 \ LMK杀进程回收等。fast path 回收不进行回写 回收的内容是匿名页 swapout 或者 file-backed 页写回和清空。假设手机都是 swap file 都是内存不是 disk, 涉及到 file 的都可能操作 io增加 block io 的概率。 还有更常见的是打开之前打开过的应用没有第一次打开的快需要加载或者卡一段时间 . 可能发生了 do_page_fault这条路径经常见到 block io 在 wait_on_page_bit_killable()如果是 swapout 内存就要 swapin 了。如果是普通文件就要 read out in pagecache/disk. do_page_fault — lock_page_or_retry - wait_on_page_bit_killable 里面会判断 page 是否置位 PG_locked, 如果置位就一直阻塞, 直到 PG_locked 被清除 , 而 PG_locked 标志位是在回写开始时和 I/O 读完成时才会被清除而 readahead 到 pagecache 功能也对 block io 产生影响太大了增加阻塞概率。 四、实例 下面这个 Trace 是低内存情况下 抓取的一个 App 的冷启动 我们只取应用启动到第一帧显示的部分 总耗时为2s 。 可以看到其 Running 的总时间是 682 ms 1、低内存的启动情况 低内存情况下 , 这个 App 从 bindApplication 到第一帧显示 , 共花费了 2s . 从下面的 Thread 信息那里可以看到 Uninterruptible Sleep | WakeKill - Block I/O 和 Uninterruptible Sleep 这两栏总共花费 750 ms 左右(对比下面正常情况才 130 ms)Running 的时间在 600 ms (对比下面正常情况才 624 ms , 相差不大)从这段时间内的 CPU 使用情况来看 , 除了 HeapTaskDaemon 跑的比较多之外 , 其他的内存和 io 相关的进程也非常多 , 比如若干个 kworker 和 kswapd0. 2、正常内存情况下 正常内存情况下 , 这个 App 从 bindApplication 到第一帧显示 , 只需要 1.22s . 从下面的 Thread 信息那里可以看到 Uninterruptible Sleep | WakeKill - Block I/O 和 Uninterruptible Sleep 这两栏总共才 130 ms.Running 的时间是 624 ms 从这段时间内的 CPU 使用情况来看 , 除了 HeapTaskDeamon 跑的比较多之外 , 其他的内存和 io 相关的进程非常少. 五、Low memory处理建议 1. 优化系统进程内存占用 参考 Quick Start Advanced System Debug Tuning Method Memory  memory usage分析 排查内存占比高进程并优化 2. 减少reserved memory 2-1 获取reserved memory 讯息 Android P , 参考FAQ21499reserve_memory 用量 Android Q, 请提e-service 申请 “memory-layout-parser” 工具 也可从lk log 搜mblock_reserve-R (但可能有缺漏) Line 1920: [1604] mblock_reserve-R[3].start: 0x46000000, sz: 0x400000 map:0 name:lk_addr_mb Line 1921: [1605] mblock_reserve-R[4].start: 0x46900000, sz: 0x8000000 map:0 name:scratch_addr_mb Line 1922: [1606] mblock_reserve-R[5].start: 0x44000000, sz: 0x80000 map:1 name:dtb_kernel_addr_mb Line 1923: [1607] mblock_reserve-R[6].start: 0x40008000, sz: 0x3200000 map:0 name:kernel_addr_mb Line 1924: [1608] mblock_reserve-R[7].start: 0x45000000, sz: 0x1000000 map:0 name:ramdisk_addr_mb Line 1925: [1609] mblock_reserve-R[8].start: 0x77370000, sz: 0xc90000 map:0 name:framebuffer Line 1926: [1610] mblock_reserve-R[9].start: 0x7fa00000, sz: 0x400000 map:0 name:logo_db_addr_pa Line 1927: [1611] mblock_reserve-R[10].start: 0x77360000, sz: 0x10000 map:0 name:SPM-reserved Line 1928: [1612] mblock_reserve-R[11].start: 0x77350000, sz: 0x10000 map:0 name:MCUPM-reserved Line 1929: [1613] mblock_reserve-R[12].start: 0x72000000, sz: 0x4000000 map:0 name:ccci 或是lk 代码搜 mblock_reserve 或 mblock_reserve_ext ex: 230  logo_db_addr_pa (void *)(u32)mblock_reserve_ext(g_boot_arg-mblock_info, 231  LK_LOGO_MAX_SIZE, PAGE_SIZE, 0x80000000, 0, logo_db_addr_pa); 或.dts 搜 reserved-memory ex: 318 reserve-memory-scp_share { 319 compatible mediatek,reserve-memory-scp_share; 320 no-map; 321 size 0 0x01400000; /*20 MB share mem size */ 322 alignment 0 0x1000000; 323 alloc-ranges 0 0x40000000 0 0x50000000; /*0x4000_0000~0x8FFF_FFFF*/ 324 }; 325 consys-reserve-memory { 326 compatible mediatek,consys-reserve-memory; 327 no-map; 328 size 0 0x200000; 329 alignment 0 0x200000; 330 alloc-ranges 0 0x40000000 0 0x80000000; 3. 限制后台 3-1修改DEFAULT_MAX_CACHED_PROCESSES /frameworks/base/services/core/java/com/android/server/am/ActivityManagerConstants.java or ProcessList.java public int MAX_CACHED_PROCESSES DEFAULT_MAX_CACHED_PROCESSES; private static final int DEFAULT_MAX_CACHED_PROCESSES 32; // 改为DEFAULT_MAX_CACHED_PROCESSES 8 or 16 or ... 3-2修改mCachedRestoreLevel /frameworks/base/services/core/java/com/android/server/am/ProcessList.java中 long getCachedRestoreThresholdKb() { return mCachedRestoreLevel; //将mCachedRestoreLevel 改为 mCachedRestoreLevel/2 } 4. 调整lmk参数 4-1. 调整minfree table kernel-4.9 non-ago project or kernel-4.14 (ro.lmk.use_minfree_levels1) minfree table后三项阀值 分别增大1.x倍 1.x倍1.x倍 (ex: 1.2 , 1.5 ...倍) minfree table 参考 Quick Start Advanced System Debug Tuning Method Memory lmkd lmk 4-2. 调整lmkd 参数 Ago project , or kernel-4.14 (ro.lmk.use_minfree_levels0) ro.lmk.medium 调小mediaum pressure kill adj 减小 更多进程可杀 ro.lmk.downgrade_pressure 调大更容易进到mediaum pressure状态 ro.lmk.upgrade_pressure 调大更容易进到critical pressure状态 5. swap szie swappiness 5-1.调大swap size, 使系统逻辑内存延伸加大 /device/mediatek/mt6xxx/ /device/mediatek/vendor/common/ fstab.enableswap fstab.enableswap_gmo fstab.enableswap_ago /dev/block/zram0 none swap defaults zramsizexx% 把值或百分比调大 可从/proc/zraminfo确认是否生效 5-2.调大swappiness, 使系统充分利用swap 分区 /proc/sys/vm/swappiness /dev/memcg/memory.swappiness /dev/memcg/apps/memory.swappiness /dev/memcg/system/memory.swappiness 6. Duraspeed enable (or 做好后台管理) duraspeed 可主动管理后台进程与内存 避免进入内存恶劣情况 7. 其他优化方案 提高 extra_free_kbytes 值提高 disk I/O 读写速率如用 UFS3.0用固态硬盘避免设置太大的 read_ahead_kb 值使用 cgroup 的 blkio 来限制后台进程的 io 读操作缩短前台 io 响应时间提前做内存回收的操作避免在用户使用应用时碰到而感受到稍微卡顿增加 LMK 效率避免无效的 killkswapd 周期性回收更多的 high 水位调整 swappiness 来平衡 pagecache 和 swap策略 : 针对低内存机器做特殊的策略 , 比如杀进程更加激进 (这会带来用户体验的降低 , 所以这个度需要兼顾性能和用户体验)策略 : 在内存不足的时候提醒用户(或者不提醒用户) , 杀掉不必要的后台进程 .策略 : 在内存严重不足且无法恢复的情况下 , 可以提示用户重启手机. 八.Slab内存占用以致Kill应用程序问题分析 一般的都是有应用程序向系统申请内存但是系统发现剩余的内存大小无法满足当前的申请进行一系列的操作之后还是无法满足将会选择最合适的程序将其kill这样系统将可以回收它的内存从而满足系统中其他进程的内存需求。所以程序被kill掉并不一定说该程序有内存泄露只是说当系统内存被kill时它最适合被kill。 在程序被kill之前可以查看进程占用的内存信息看看进程是否存在内存泄露 其中部分信息如下 VmPeak: 3068 kB VmSize: 3068 kB VmLck: 0 kB VmPin: 0 kB VmHWM: 612 kB VmRSS: 612 kB 我们主要查看VmRSS的大小是否逐渐在增大如果该值逐渐增大很大可能是程序存在内存泄露。但是在test测试中程序的该值并没有很明显的变化所以转向系统内存信息。 每隔一段时间查看系统内存的信息操作如下 rootLinux: /# cat /proc/meminfo MemTotal: 493184 kB MemFree: 442572 kB MemAvailable: 452300 kB Buffers: 3424 kB Cached: 3224 kB SwapCached: 0 kB Active: 8940 kB Inactive: 284 kB Active(anon): 2588 kB Inactive(anon): 120 kB Active(file): 6352 kB Inactive(file): 164 kB Unevictable: 0 kB Mlocked: 0 kB HighTotal: 0 kB HighFree: 0 kB LowTotal: 493184 kB LowFree: 442572 kB SwapTotal: 0 kB SwapFree: 0 kB Dirty: 20 kB Writeback: 0 kB AnonPages: 2616 kB Mapped: 2204 kB Shmem: 124 kB Slab: 30528 kB SReclaimable: 13904 kB SUnreclaim: 16624 kB KernelStack: 704 kB PageTables: 296 kB NFS_Unstable: 0 kB Bounce: 0 kB WritebackTmp: 0 kB CommitLimit: 246592 kB Committed_AS: 55424 kB VmallocTotal: 507904 kB VmallocUsed: 0 kB VmallocChunk: 0 kB CmaTotal: 65536 kB CmaFree: 59280 kB 通过cat /proc/meminfo查看系统的内存信息其中Slab是slab占用的内存大小SReclaimable是可回收的而SUnreclaim是不可回收的。发现Slab占用了系统快30M的内存留意这个信息。接着再查看一下slab的详细使用情况 rootLinux: /# cat /proc/slabinfo slabinfo - version: 2.1 # name active_objs num_objs objsize objperslab pagesperslab : tunables limit batchcount sharedfactor : slabdata active_slabs num_slabs sharedavail ext4_groupinfo_4k 58 81 296 27 2 : tunables 0 0 0 : slabdata 3 3 0 ext4_groupinfo_1k 1 28 288 28 2 : tunables 0 0 0 : slabdata 1 1 0 jbd2_1k 0 0 3072 10 8 : tunables 0 0 0 : slabdata 0 0 0 bridge_fdb_cache 0 0 320 25 2 : tunables 0 0 0 : slabdata 0 0 0 sd_ext_cdb 2 18 216 18 1 : tunables 0 0 0 : slabdata 1 1 0 sgpool-128 2 14 2304 14 8 : tunables 0 0 0 : slabdata 1 1 0 sgpool-64 2 25 1280 25 8 : tunables 0 0 0 : slabdata 1 1 0 sgpool-32 2 21 768 21 4 : tunables 0 0 0 : slabdata 1 1 0 sgpool-16 2 16 512 16 2 : tunables 0 0 0 : slabdata 1 1 0 sgpool-8 2 21 384 21 2 : tunables 0 0 0 : slabdata 1 1 0 cfq_io_cq 10 31 264 31 2 : tunables 0 0 0 : slabdata 1 1 0 cfq_queue 9 22 360 22 2 : tunables 0 0 0 : slabdata 1 1 0 fat_inode_cache 3 26 616 26 4 : tunables 0 0 0 : slabdata 1 1 0 fat_cache 0 0 200 20 1 : tunables 0 0 0 : slabdata 0 0 0 squashfs_inode_cache 88 200 640 25 4 : tunables 0 0 0 : slabdata 8 8 0 jbd2_transaction_s 0 42 384 21 2 : tunables 0 0 0 : slabdata 2 2 0 jbd2_inode 1 76 208 19 1 : tunables 0 0 0 : slabdata 4 4 0...... kmalloc-128 1589 1596 384 21 2 : tunables 0 0 0 : slabdata 76 76 0 kmalloc-64 15937 16200 320 25 2 : tunables 0 0 0 : slabdata 648 648 0 kmem_cache_node 107 125 320 25 2 : tunables 0 0 0 : slabdata 5 5 0 kmem_cache 107 126 384 21 2 : tunables 0 0 0 : slabdata 6 6 0 从这里可以了解到slab的使用情况记录下来。 slab是Linux操作系统的一种内存分配机制。其工作是针对一些经常分配并释放的对象如进程描述符等这些对象的大小一般比较小如果直接采用伙伴系统来进行分配和释放不仅会造成大量的内碎片而且处理速度也太慢。而slab分配器是基于对象进行管理的相同类型的对象归为一类(如进程描述符就是一类)每当要申请这样一个对象slab分配器就从一个slab列表中分配一个这样大小的单元出去而当要释放时将其重新保存在该列表中而不是直接返回给伙伴系统从而避免这些内碎片。slab分配器并不丢弃已分配的对象而是释放并把它们保存在内存中。当以后又要请求新的对象时就可以从内存直接获取而不用重复初始化。 接着将可以隔较长一段时间重复的进行cat /proc/meminfo和cat /proc/slabinfo操作对比几次的信息检查问题。 最后发现经过较长一段时间的测试之后Slab占用的内存数量大大增加如果是slab占用较大的内存则是内核频繁分配结构体导致导致系统可用内存减小。直到出现Out of memory导致kill程序。 1.解决 了解到是Slab导致的占用内存过高的问题之后可以手动的刷Slab操作如下 echo 3 /proc/sys/vm/drop_caches /* 回刷缓冲 */ 其中drop_caches的4个值有如下含义 0不做任何处理由系统自己管理1清空pagecache2清空dentries和inodes3清空pagecache、dentries和inodes 但是这样的办法不是最佳的最好还是应该通过slabinfo信息了解到应用程序进行什么操作导致内核频繁申请结构体导致Slab占用大量内存看能否避免这样的问题同时内核有自动回收机制可修改触发自动回收的阀值当slab空闲内存达到一定量的时候进行有效的回收。 2.后续 后来在参考文章看到信息概括如下 文中开头的说到的老化测试程序test就是大量的保存文件频繁的文件io操作open、write、close导致了dentry_cache占用了系统太多的内存资源。 inode对应于物理磁盘上的具体对象而dentry是一个内存实体其中的d_inode成员指向对应的inode故可以把dentry看成是Linux文件系统中某个索引节点(inode)的链接这个索引节点可以是文件也可以是目录。而dentry_cache是目录项高速缓存是Linux为了提高目录项对象的处理效率而设计的它记录了目录项到inode的映射关系。 3.系统的自动slab缓存回收 在slab缓存中对象分为SReclaimable可回收和SUnreclaim不可回收而在系统中绝大多数对象都是可回收的。内核有一个参数当系统内存使用到一定量的时候会自动触动回收操作。 内核参数 vm.min_free_kbytes 836787 代表系统所保留空闲内存的最低限。 在系统初始化时会根据内存大小计算一个默认值计算规则是 min_free_kbytes sqrt(lowmem_kbytes * 16) 4 * sqrt(lowmem_kbytes)(注lowmem_kbytes即可认为是系统内存大小 另外计算出来的值有最小最大限制最小为128K最大为64M。 可以看出min_free_kbytes随着系统内存的增大不是线性增长因为随着内存的增大没有必要也线性的预留出过多的内存能保证紧急时刻的使用量便足矣。min_free_kbytes的主要用途是计算影响内存回收的三个参数 watermark[min/low/high] watermark[high] watermark [low] watermark[min]各个zone各一套在系统空闲内存低于 watermark[low]时开始启动内核线程kswapd进行内存回收每个zone一个直到该zone的空闲内存数量达到watermark[high]后停止回收。如果上层申请内存的速度太快导致空闲内存降至watermark[min]后内核就会进行direct reclaim直接回收即直接在应用程序的进程上下文中进行回收再用回收上来的空闲页满足内存申请因此实际会阻塞应用程序带来一定的响应延迟而且可能会触发系统OOM。这是因为watermark[min]以下的内存属于系统的自留内存用以满足特殊使用所以不会给用户态的普通申请来用。三个watermark的计算方法 watermark[min] min_free_kbytes换算为page单位即可假设为min_free_pages。因为是每个zone各有一套watermark参数实际计算效果是根据各个zone大小所占内存总大小的比例而算出来的per zone min_free_pages watermark[low] watermark[min] * 5 / 4 watermark[high] watermark[min] * 3 / 2 所以中间的buffer量为 high - low low - min per_zone_min_free_pages * 1/4。因为min_free_kbytes 4* sqrt(lowmem_kbytes也可以看出中间的buffer量也是跟内存的增长速度成开方关系。可以通过/proc/zoneinfo查看每个zone的watermark min_free_kbytes大小的影响 min_free_kbytes设的越大watermark的线越高同时三个线之间的buffer量也相应会增加。这意味着会较早的启动kswapd进行回收且会回收上来较多的内存直至watermark[high]才会停止这会使得系统预留过多的空闲内存从而在一定程度上降低了应用程序可使用的内存量。极端情况下设置min_free_kbytes接近内存大小时留给应用程序的内存就会太少而可能会频繁地导致OOM的发生。 min_free_kbytes设的过小则会导致系统预留内存过小。kswapd回收的过程中也会有少量的内存分配行为会设上PF_MEMALLOC标志这个标志会允许kswapd使用预留内存另外一种情况是被OOM选中杀死的进程在退出过程中如果需要申请内存也可以使用预留部分。这两种情况下让他们使用预留内存可以避免系统进入deadlock状态。 可测试当调整完min_free_kbytes值大于系统空闲内存后kswapd进程的确从休眠状态进入运行态开始回收内存。 同时还有一个参数vm.vfs_cache_pressure 200 该文件表示内核回收用于directory和inode cache内存的倾向缺省值100表示内核将根据pagecache和swapcache把directory和inode cache保持在一个合理的百分比降低该值低于100将导致内核倾向于保留directory和inode cache增加该值超过100将导致内核倾向于回收directory和inode cache。
http://www.dnsts.com.cn/news/177165.html

相关文章:

  • 石家庄网站建设报价网站建设选哪家公司
  • 电商网站开发经验网站建设论文范文
  • 网站推广营销运营方式上海有什么大企业
  • 受欢迎的网站建设案例html网页设计规则代码
  • 西安市做网站公司网页美工设计流程为
  • 网站建设备案书模板中国能建官网
  • 外贸网站制作时间及费用谷歌账号注册网站打不开
  • 霸州做网站的动漫设计属于什么专业
  • 湘西做网站企业宣传网站在哪里做
  • 宁波高端网站制作公司做外贸需要哪些网站
  • 网站注销主体wordpress数据连接信息
  • 网站建设教程视频网页制作软件免费版无需登录
  • 医院网站建设方案招标文件wordpress常规选项
  • html转换器seo资源网站排名
  • 制作团购网站网站建设公司测评
  • 建设厅查询网站厦门网站建设有限公司怎么样
  • 网站是否含有seo收录功能简洁的wordpress主题
  • 网站版面设计注意事项wordpress ajax钩子
  • 金华企业制作网站注册公司怎么注销
  • 网站开发设计作业及代码网络建设工作总结
  • 网站建设周期表移动互联网应用程序管理情况
  • 惠州网站制作网站制作app需要学哪些知识
  • 用织梦做视频网站网站建设完成汇报
  • 服装公众号的手机网站怎么做注册会计师考试科目
  • 常州网站推广软件信息粉红色的网站首页
  • 局域网网站域名怎么做东莞品牌网站建设
  • 银川做网站设计的公司免费搭建个人博客网站
  • 做外贸哪个网站可以接单提升排名
  • 廊坊市 广阳区城市建设局网站河北建设教育培训网站
  • 开发网站访问流量赚钱做网页的软件哪个好