【Android Linux内存及性能优化】(六) 系统内存的优化
发布日期:2021-06-29 14:52:04 浏览次数:2 分类:技术文章

本文共 5596 字,大约阅读时间需要 18 分钟。

【Android Linux内存及性能优化】六 系统内存的优化

本文接着

《》
《》
《》
《》
《》

一、内存篇

1.1 系统当前可用内存

1.2 进程的内存使用

1.3 进程内存优化

1.4 系统内存优化

1.4.1 守护进程的内存使用

在设备开机之后,你会发现已经有很多进程在运行,这些进程将一直存活,直到设备关机,我们把这类进程称为守护进程。

守护进程对系弘的内存使用影响巨大:

(1)由于守护进程一直存活,所以其所占用的内存将不会被释放。
(2)一个进程即使什么事情都不做,它引用了一些动态库,也会占用大量的物理内存。
(3)由于守护进程的生存周期很长,其哪怕只有一点内存泄漏,也会导致系统的内存耗尽。

进程一旦退出,其所占用的内存存将被 Linux内核收回,所以对那些生存周期很短的进程来讲,即使有些内存泄漏,其对系统内存使用影响并不大。

因些应该尽量减少系统中守护进程的数量,对于那些提供服务的守护进程来讲,尽量做到在进程需要的时候来启动,在不需要的时候退出。

下面就来详细描述如何减少守护进程的数量。

首先为什么会存在守护进程? 原因主要两点:

  1. 系统需要守护进程来侦听某些事件。

    在设计守护进程时,开发人员往往没有区分其中的常驻部分和非常驻部分,
    在侦听到一个事件后,直接启动相应的业务逻辑,而在这些业务逻辑执行完之后,并不会将本已无用的业务逻辑部分释放。
    这样就造成了侦听部分与业务逻辑部分混在一起都作为守护进程,
    而使得守护进程部分逻辑比较复杂,一方面占用了大量的内存,另一方面也增大了内存泄漏的几率。

    因些建议将守护进程明确分为常驻部分和非常驻部分,分别让不同的进程来完成,将常驻内存部分的逻辑尽量简化

    更进一步,可以考虑将几个守护进程的侦听事件部分合并到一个守护进程,当负责侦听的守护进程收到消息后,再去启动相应的业务逻辑。

    在这一方面,inetd 是最好的例子,其常驻内部部分可以侦听 telnet、ftp等端口,在有用户该问后,又会创建相应的进程为用户提供服务。

  1. 有些进程提供服务的响应时间达不到要求,开发人员便将其放在设备开机时启动,所以转变为了守护进程。
    首先需要考虑加快进程的启动速度,从而使服务进程达到按需启动的需求,这个后续分析。
    除了优化加载动态库、使用 Prelink 等方法外,还可以采用一些进程调度的方法来减少守护进程对于内存的影响。

1.4.2 tmpfs 分区

在LInux 中,为了加快对文件的读写,基于内存建立了一个文件系统,称为 ramdisk 或者 tmpfs。

对于该文件系统的访问,都将直接操作物理内存,因此而要比访问Flash 快得多。

在做系统内存优化时,不要忘掉这块内存。

ciellee@sh:~/work/code/simcom_220c_sop_1028_0426$ df  -HFilesystem      Size  Used Avail Use% Mounted onudev            8.4G     0  8.4G   0% /devtmpfs           1.7G   11M  1.7G   1% /run/dev/sda8       706G  520G  150G  78% /tmpfs           8.4G  180M  8.2G   3% /dev/shmtmpfs           5.3M  4.1k  5.3M   1% /run/locktmpfs           8.4G     0  8.4G   0% /sys/fs/cgroup/dev/loop0       99M   99M     0 100% /snap/core/9066

可以看出,tmpfs 文件分区为8.4G。

在对这个文件分区进行读写时,要时刻提醒自已,它是占用物理内存的,在该分区上的文件,不需要的时候应及时删除。

1.4.3 Cache 缓存 和 Buffer 缓冲

前面讲到, 系统中空闲内存 = MemFree + Buffers + Cached。

下面我们来看下 Cache 和 Buffer 分别是什么。

1.4.3.1 Cache 缓存

Cache 也称缓存,是把从Flash 中读取的数据保存起来,

若再次读取该块数据时,就不需要去读取Flash 了,直接从缓存中读取,从而提高读取文件的速度。

Cache 缓存的数据会根据读取频率进行组织,把最频繁读取的内容 放在最容易找到的位置,把不再读的内容不断往后排,直至从中删掉。

在程序执行过程中,发现某些指令不在内存中,便会产生 page fault,而将代码段的数据载入到物理内存。当进程退出后,代码段所占用的内存不会完全丢弃,而是作为Cache 缓存在Linux 系统中。当进程运行时,Cache 的代码指令越多,代码段产生 page fault 的几率越小,程序的执行速度也越快,这便是Cache 存在的理由。

1.4.3.2 Buffer 缓冲

Buffer 也称缓冲,是根据Flash 读写设计的,把分散的写操作集中进行,减小Flash 写的次数,从而提高系统性能。

Cache 和 Buffer 的区别,简单来说,两者都是RAM 中的数据,

Buffer 是缓冲即将写入磁盘的数据, 而 Cache 是缓存从磁盘中读取出来的数据。

在系统内存不足时,Linux 内核会将一部分 Cache 和 Buffer 释放,供进程使用,因此Cache 和Buffer 对于进程的内存使用并没有影响。

可以通过 cat /proc/meminfo 来了解系统中 Cache 和Buffer 的大小:

ciellee@sh:~/work/code/simcom_220c_sop_1028_0426$ cat /proc/meminfo MemTotal:       16281312 kBMemFree:          178828 kBMemAvailable:   13359384 kBBuffers:          426416 kBCached:         13052476 kBSwapCached:            0 kBActive:          2841180 kBInactive:       12108016 kB

1.4.3.3 内存回收

在 LInux 中,有一个内核进程 kswapd ,其专门负责回收内存。

在 kswapd 中,有2 个阈值: pages_high 和 pages_low ,

当空闲内存页的数量低于 pages_low 的时候,kswapd 进程就会扫描内存并且每次释放出 32 个 free pages,直到 free page 的数量到达 pages_high。

(1)kswapd 回收内存有如下原则:
  1. 如果物理页面不量 dirty page,就将物理页面回收。

    进程中如下内存可能是非 dirty page页面:
    (1)代码段:其权限是只读属性,不可能被改写,所以其所占的物理内存,都不是dirty page。
    (2)数据段:其权限是可读、可写,所以其所占的物理内存可能是 dirty page,也可能不是。
    (3)堆段:其权限是可读、可写,空容全是通过程序改写的,所以其所占用的物理内存,全部是 dirty page。
    (4)栈段 和 堆段 相同,其所占的物理内存,全部是 dirty page。
    (5)共享内存,其所占的物理内存,全部是 dirty page。

    综上: 这条规则主要面向的是进程的代码段 和 未修改的数据段。

    如果你做过长时间的系统进程使用分析,就会发现,在进程跑了一段时间后,其代码所占的物理内存减少了,这就是代码段内存回收的结果。

  2. 如果物理页面已经修改 并且 可以备份回文件系统,就调用 pdflush 将内存中的内容 和文件系统进行同步。同步完成后,就可以将内存释放。

    比如,当一个文件在内存中进行修改,pdflush 负责将其写回磁盘,其主要针对的是下 Buffers。

  3. 如果物理页面已经修改但是没有任何磁盘的备份,就将其写入 swap 分区。

    实际上大部分嵌入式设备很少有交换分区,因此这条规则根本不起作用。

kswapd 在回收内存过程中还有两个重要的方法:

一是 LMR (Low on memory reclaiming),另一个是 OMK(Out of Memory Killer)。

当分配内存失败的时候,LMR将会起作用,失败的原因是 kswapd 不能提供足够的空闲内存,这个时候LMR 会每次释放1024 个垃圾页直到内存分配成功。

当LMR 不能快速释放内存的时候,OMK 就开始起作用,OMK 会采用一个选择算法来决定杀死某些进程,选定进程后,就会发送信号 SIGKILL,这就会使内存立即被释放。

(2)OMK 选择进程的标准如下:
  1. 进程占用大量的内存。
  2. 进程只会损失少量工作。
  3. 进程具有低的静态优先级。
  4. 进程不属于 root 用户。

1.4.3.4 /proc/sys/vm/优化

可以通过修改 /proc/sys/vm 下面的文件,设置一些参数,来影响 LInux内核的一些内存操作行为。

修改 /proc/ 下文件的方法:

  1. # echo 1 > /proc/sys/vm/block_dump

    该文件表示是否打开 Block Debug 模式,用于记录所有的读写及 Dirty Block写回动作。
    缺省设置 :0,禁用 Block Debug。

  2. # echo 10 > /proc/sys/vm/dirty_background_ratio

    该文件表示脏数据到达系统整体内存的百分比,此时触发 pdflush 进程把脏数据写回磁盘。
    缺省设置:10, 10%

  3. # echo 3000 > /proc/sys/vm/dirty_expire_centisece

    该文件表示如果脏数据在内存中驻留时间超过该值,pdflush 进程在下一次将把这些数据写回磁盘。
    缺省设置:3000, (1/100)s

  4. # echo 40 > /proc/sys/vm/dirty_ratio

    该文件表示如果进程产生的脏数据到达系统整体内存的百分比,此时进程自行把脏数据写回磁盘。
    缺省设置:40, 40%

  5. # echo 500 > /proc/sys/vm/dirty_writeback_centisecs

    该文件表示pdflush 进程周期间隔多久把脏数据写回磁盘。
    缺省设置:500, (1/100)s

  6. # echo 100 > /proc/sys/vm/vfs_cache_pressure

    该文件表示内核回收用于directory 和 inode cache 内存的倾向,
    缺省 100 表示内核将根据 pagecache 和 swapcache ,把 directory 和 inode cache 保持在一个合理的百分比;
    降低该值于 100,将导致内核倾向于保留 directory 和 inode cache 。
    增加该值超过 100 ,将导致内核倾向于回收 directory 和 inode cache 。
    缺省设置:100

  7. # echo 724 > /proc/sys/vm/min_free_kbytes

    该文件表示强制 Linux VM 最低保留多少空闲内存(KB),缺省值:724

  8. # cat /proc/sys/vm/nr_pdflush_threads

    该文件表示当前正在运行的 pdflush 进程数量,在I/O 负载高的情况下,内核会自动增加更多的pdflush 进程,缺省值:2(只读)

  9. # echo 0 > /proc/sys/vm/overcommit_memory

    该文件指定了内核针对内存分配的策略,其值可以是:0、1、2,缺省值:0
    0:表示内核将检查是否有足够的可用内存供应进使用,如果有足够的可用内存,内存申请允许,否则内存申请失败,并把错误返回给应用进程。
    1:表示内核允许分配所有的物理内存,而不管当前的内存状态如何。
    2:表示内核允许分配超进所有物理内存和交换空间总和的内存。

  10. # echo 50 > /proc/sys/vm/overcommit_ratio

    该文件表示,如果 overcommit_memory = 2 ,可以过载内存的百分比,通过以下公式来计算系统整估可用内存:
    系统可分配内存 = 交换空间 + 物理内存 × overcommit_ratio / 100。
    缺省设置:50%

  11. # echo 3 > /proc/sys/vm/page-cluster

    该文件表示在写一次到swap 区的时候写入的页面数量,0: 表示1页, 1:表示2页,2表示4页, 缺省3:2^3=8页。

  12. # echo 60 > /proc/sys/vm/swapiness

    该文件表示,系统进行交换行为的程序,数值(0~100)越高,越可能发生磁盘交换,缺省60

  13. # echo 0 > /proc/sys/vm/legacy_va_layout

    该文件表示是否使用最新的32位共享内存 mmap() 系统调用,Linux 支持的共享内存分配方式包括mmap(), Posix, System VIPC,缺省 0
    0:表示使用最新的32位 mmap() 系统调用
    1:表示使用 2.4 内核提供的系统调用

  14. # cat /proc/sys/vm/nr_hugepages

    该文件表示系统保留的 hugetlb 页数。

转载地址:https://ciellee.blog.csdn.net/article/details/106357011 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:【倒车影像分流需求 四】- 保存视频数据为yuv 图
下一篇:【FFMPEG】华为新老两手机平台编码的视频,在同一车机上投屏解码时间慢的问题分析

发表评论

最新留言

初次前来,多多关照!
[***.217.46.12]2024年04月15日 14时43分48秒