| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 系统运维 -> Linux嵌入式设备内存问题定位 -> 正文阅读 |
|
[系统运维]Linux嵌入式设备内存问题定位 |
????????Linux嵌入式设备的内存一般都不大,可能就只有32M、64M、128M、256M。无线路由器一般以64M和128M居多。之前用的64M内存的方案,由于做海外版本,增加功能,导致了内存不足,因此总结了部分经验,提供给大家,希望大家调试过程少走弯路。 一、内存不足的现象a. 在多个无线终端挂机时,出现系统运行缓慢,甚至OOM b. 新建性能数据低 c. 在跑大流量转发时,出现内存不足 d. 全配置下,各种功能开启时,出现内存不足 e. 内存碎片变多 由于内存不足情况,一般需要在长时间挂机的情况下出现,复现成本高,因此需要在系统设计或转测初期关注,如果到了项目后期,那基本上会阻塞项目进度,因此掌握三板斧来定位分析内存问题很重要。 二、关注系统内存方法在Linux下基本由应用层内存和内核占用内存,这两块一会重点分析。 1、rootfs对于嵌入式设备,rootfs的文件系统也是需要关注的,因为它没有所谓的硬盘,只有Flash,运行时无论是内核或是应用的可执行进程,都需要加载至内存。 ~ # mount rootfs on / type rootfs (rw) /dev/root on / type squashfs (ro,relatime) 以上示例用的是squashfs,这个文件系统是只读的,好处在于如果某个文件不用时,会处于Flash中,并不会加载至内存。 笔者很早以前用于ramfs的rootfs,这个文件系统会全部加载至内存,现在使用这种rootfs的产品很少了,毕竟内存有限。 但这不意味着rootfs大了也没有影响,相反,通过rootfs的裁剪是个必要也是很效的方案。 现在厂商编译用lzma的居多,压缩前的文件系统在30M左右,压缩后大约为6M多,压缩比6~7,因为Linux在运行时,如etc、var、tmp等目录,需要挂载为可读可写,同时web文件也占有一定大小(即使WEB目录挂载为ro,也会在访问时加载到内存),因此对于文件系统中的每个可执行文件、每个配置文件,需要了解其具体的用途,如果用不到,则不必放到文件系统中,这个非常考验我们对开发系统的了解。 2、内核占用的内存在编译内核时,需要审查.config文件,看里面是否有用不到的或不合理的配置。 内存页大小,配置为4K 去除不必要的文件系统支持,如jffs2、yaffs2、ubi 支除不必要的编码支持 查看网络配置中的option配置、netfilter配置、l2tp/pptp/ipsec等一些协议支持 关闭一些debug特性,如kallsyms 关闭一些用不到厂商设备支持,如usb、I2C、485 ...... 这部分裁剪会有直观的效果,越早去裁越好,对网络设备而言,11ac、11ax的无线驱动会占较大空间,尤其BRCM方案。 运行时内存同样重要,且需要关注 ~ # cat /proc/meminfo? ... Slab:? ? ? ? ? ? ? 18196 kB SReclaimable: ? ? ? 2432 kB SUnreclaim:? ? ? ? 15764 kB KernelStack: ? ? ? ? 608 kB PageTables:? ? ? ? ? 476 kB ... 如上,我们关注kernel stack大小,以及slab占用内存的情况,提到slab又要讲一堆了。slab用于Linux的内存申请,是伙伴系统buddy的精细化管理。可以简单直接为除了内核栈及预分派的DMA内存,动态内存都要通过slab来分配,通过对比系统启动时的slab信息和运行中的slab信息,我们能对比分析出内存用在哪里了。 ~ # cat /proc/slabinfo? slabinfo - version: 2.1 # name? ? ? ? ? ? : tunables : slabdata nf_conntrack_c04dc59c? ? 437? ? 456? ? 416 ? 19? ? 2 : tunables? ? 0? ? 0? ? 0 : slabdata ? ? 24 ? ? 24? ? ? 0 如上,我们以链接跟踪数为例,链接跟踪是随着网络连接数据增加而增加的,即用户访问一条TCP/UDP连接,对应着系统就要占用相应的ct结构体(我们不讨论连接的保持及超时机制)。 现有连接数为437个(active_objs),当前系统有456个ct结构体,每个结构体大小为416 B(objsize),在这里可以看到: 1、nf_conntrack为专用缓存,通过调用kmem_cache_create接口来创建,这样的好处是非常直观的看到模块占用了多少内存,如果内存消耗是线性递增的,那起个好名字会非常方便定位问题,好的实现也应该如此。 2、系统已经申请了456个ct,但当前只用了437个,体现了缓存的概念。 3、每一次slab为此结构体使用从2个页(pagesperslab),提供19(objperslab)个ct结构体 4、当前的slabs数为24(num_slabs),共占用了, 24*2 * page_size = 48*4K = 192K内存 5、假设系统配置的最大ct数为2万,则需要占用 20000/19*2*4K = 8421K,也就是8M内存,此时我们得看下内存是否足够支撑,同时一些网络内核模块也依赖于ct或维护了另一个ct,那么这个线性的过程,就必然是内存考量的重点。 未完成待续分析应用层占用内存,是否存在泄露,关注物理内存 查看内存碎片化情况buddyinfo 关注最小内存配置min_free_kbytes 关注内存水位阈值及调节zoneinfo 触发kswap的内存回收 OOM的配置 进程oom_score_adj配置 调节应用层内存的使用:受限服务及服务恢复 |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/25 18:46:30- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |