Linux内存使用调整
前段时间在做播放器的时候,遇到个问题,花了很长时间,做个记录,希望对有需要的人有所帮助:
播放器的播视频的时候,无论是手动切换视频还是到视频播放完成,自动切换视频,一定次数后均出现黑屏现象,偶尔有声音,问题出现后,不可恢复,Kernel输出如下Log:
DMA free:71672kB min:616kB low:768kB high:924kB active_anon:0kB inactive_anon:0kB active_file:0kB inactive_file:0kB unevictable:0kB isolateds
lowmem_reserve[]: 0 1244 1593 1593
Normal free:1249804kB min:4212kB low:5264kB high:6316kB active_anon:0kB inactive_anon:0kB active_file:0kB inactive_file:0kB unevictable:0kB o
lowmem_reserve[]: 0 0 2794 2794
HighMem free:223000kB min:348kB low:640kB high:936kB active_anon:39248kB inactive_anon:140kB active_file:61020kB inactive_file:34108kB unevio
lowmem_reserve[]: 0 0 0 0
DMA: 22*4kB 90*8kB 21*16kB 82*32kB 7*64kB 137*128kB 69*256kB 3*512kB 8*1024kB 5*2048kB 3*4096kB 0*8192kB 0*16384kB 0*32768kB = 71672kB
Normal: 1*4kB 53*8kB 16*16kB 6*32kB 6*64kB 4*128kB 1*256kB 1*512kB 2*1024kB 2*2048kB 3*4096kB 2*8192kB 4*16384kB 35*32768kB = 1249772kB
HighMem: 14*4kB 10*8kB 437*16kB 386*32kB 374*64kB 27*128kB 10*256kB 7*512kB 8*1024kB 7*2048kB 4*4096kB 2*8192kB 1*16384kB 3*32768kB = 223000B
23829 total pagecache pages
0 pages in swap cache
Swap cache stats: add 0, delete 0, find 0/0
Free swap = 0kB
Total swap = 0kB
524288 pages of RAM
387015 free pages
73287 reserved pages
1169 slab pages
8545 pages shared
0 pages swap cached
Physical memory allocation error!
Physical memory allocation error!
通过Log,定位到输出的位置是解码驱动中,驱动在DMA请求失败后,输出以上信息。针对这个现象,按以下几个思路进行的调查:
1. 内存泄露
在驱动中增加了一些Log,随着视频切换,分配的地址会一定程度的变大,直到最后分配失败。但仔细研究发现分配与释放是配对的,驱动中记录的内存使用信息完全正确,没有任何迹象表明有内存泄露发生。
2. 内存碎片
官论上有同样的问题登录,但无明确结论,官方应该是没重现。民间有人指出问题在于驱动请求的连续内存块比较大,但系统已无相应的内存可供分配,即内存碎片了。同时有人给出俩个方案:缓存每次的请求的内存,分配后,不再返还给系统,这个方案我测试后,发现会导致其它视频驱动出现同样问题,不可用;另一个方案是认为导致内存碎片的原因在于,文件系统的Cache机制,要解决这个问题,需要清除被Cache占用的内存,方法如下:
echo 3 > /proc/sys/vm/drop_caches
试验之后,果然有效,测试了手中的测试用例几千次后,发了测试软件,结果悲剧,开发部的测试用例几次就测出同样的问题,该方案水土不服。
3. 调查Linux内存使用
从内存碎片这个思路出发,分析什么导致了驱动的DMA空间碎片化。查了一些资料发现,Linux的内存划分分成3块:DMA,Low Memory和High Memory。一般32位PC的配置是DMA Zone位于0x00010000-0x00ffffff,大约16MB,Low Memory是0x01000000-0x37bfdfff,约800多MB,再往上的空间给High Memory,这部分的访问要通过跳转,性能不如DMA Zone和Low Memory Zone快。而内存分配的策略是从上往下分配,一旦高位的内存空间不足,则向低地址的空间请求内存。在我们的产品上,总的内存大小是512MB,某些驱动预留128MB,DMA Zone的配置是184MB,那么实际剩下的Low Memory Zone只有200MB,而这200MB要运行UI,媒体管理,互联等等一系列进程。一旦Low Memory Zone的内存不够用,系统会向DMA Zone请求内存,从而导致的DMA空间的内存碎片化!而这时,通过free命令是看不到正确的内存信息的,因为看到的空间还有,但一是被Cache占用,二是计算的是总数,而不是真正的连续内存,这时查看内存应该使用系统提供的Buddy Info来看真正剩余的内存块:
$cat /proc/buddyinfo
Node 0, zone DMA 3 1 3 4 1 2 2 0 1 2 0 3 2 2
Node 0, zone Normal 74 36 29 8 6 4 3 2 1 2 3 2 0 2
输出的数据从左侧开始是4K内存块的个数,依次乘2到最右侧的32M;在出问题时,系统基本上只有小块的内存,而问题的原因就是一些文件访问的操作导致DMA Zone的空间被Cache使用了。
4. 控制内存分配算法
找到问题的原因后,调查如何能禁止系统从DMA Zone分配内存。查找到可以设置lowmem_reserve_ratio,来告诉系统,DMA Zone的预留空间。其参数有3个(系统默认:256,32,32),与DMA Zone有关的是第一个,其值是除数,用DMA Zone的大小除以256,得到的基本就是预留的大小了。做了几个测试后,发现只有设置为1才能有效保护DMA Zone不被占用,:(!设置为1后,视频不再出现黑屏,但其他问题很快出现,因为系统可用的内存减少,内存的回收算法被频繁执行,性能急剧下降。
5. 最终方案
由于产品的总内存太小,而预留的DMA Zone太大,所以需要调整DMA Zone预留的空间,但lowmem_reserve_ratio已无调整空间,所以考虑从调整Kernel上下手。最后,将Kernel中的DMA Zone总大小由184MB调整为原来的3/4,即138MB,得到一个近似合理的配置,保证的DMA和Low Memory都可以申请到足够的空间,长时间测试后,未再现相关问题。
Linux内存使用调整的更多相关文章
- Linux内存管理原理
本文以32位机器为准,串讲一些内存管理的知识点. 1. 虚拟地址.物理地址.逻辑地址.线性地址 虚拟地址又叫线性地址.linux没有采用分段机制,所以逻辑地址和虚拟地址(线性地址)(在用户态,内核态逻 ...
- Linux内存管理原理【转】
转自:http://www.cnblogs.com/zhaoyl/p/3695517.html 本文以32位机器为准,串讲一些内存管理的知识点. 1. 虚拟地址.物理地址.逻辑地址.线性地址 虚拟地址 ...
- linux内存——/proc/sys/vm/drop_caches
原贴:http://www.linuxfly.org/post/320/ http://blog.csdn.net/chinalinuxzend/article/category/265273/2 ...
- Windows内存管理和linux内存管理
windows内存管理 windows 内存管理方式主要分为:页式管理,段式管理,段页式管理. 页式管理的基本原理是将各进程的虚拟空间划分为若干个长度相等的页:页式管理把内存空间按照页的大小划分成片或 ...
- linux 内存管理——内核的shmall 和shmmax 参数
内核的 shmall 和 shmmax 参数 SHMMAX= 配置了最大的内存segment的大小 ------>这个设置的比SGA_MAX_SIZE大比较好. SHMMIN= 最小的内存seg ...
- Cgroup - Linux 内存资源管理
Hi ,我是 Zorro .这是我的微博地址,我会不定期在这里更新文章,如果你有兴趣,可以来关注我呦. 另外,我的其他联系方式: Email: mini.jerry@gmail.com QQ: 300 ...
- 手工释放Linux内存
转载自:http://blog.csdn.net/wyzxg/article/details/7279986/ linux的内存查看: [root@localhost 0.1.0]# free -m ...
- linux内存基础知识和相关调优方案
内存是计算机中重要的部件之中的一个.它是与CPU进行沟通的桥梁. 计算机中全部程序的执行都是在内存中进行的.因此内存的性能对计算机的影响很大.内存作用是用于临时存放CPU中的运算数据,以及与硬盘等外部 ...
- 手工释放linux内存——/proc/sys/vm/drop_caches
--手工释放linux内存——/proc/sys/vm/drop_caches 总有很多朋友对于Linux的内存管理有疑问,之前一篇日志似乎也没能清除大家的疑虑.而在新版核心中,似乎对这个问题提供了新 ...
随机推荐
- HDU 1021(斐波那契数与因子3 **)
题意是说在给定的一种满足每一项等于前两项之和的数列中,判断第 n 项的数字是否为 3 的倍数. 斐波那契数在到第四十多位的时候就会超出 int 存储范围,但是题目问的是是否为 3 的倍数,也就是模 3 ...
- sqlalchemy外键和relationship查询
前面的文章中讲解了外键的基础知识和操作,上一篇文章讲解了sqlalchemy的基本操作.前面两篇文章都是作为铺垫,为下面的文章打好基础.记得初一时第一次期中考试时考的不好,老爸安慰我说:“学习是一个循 ...
- python-虚拟环境搭建
虚拟环境 需求: --公司之有一台服务器 -目前运行这一个5年前开发的Django项目,基于1.5 -现在要基于Django2.0开发一套程序 ...
- springBoot的事物管理
springBoot的事物管理 1:springBoot 整合单数据源事物: Spring Boot 使用事务非常简单,首先使用注解 @EnableTransactionManagement 开启事务 ...
- 未启用当前数据库的 SQL Server Service Broker,因此查询通知不受支持。如果希望使用通知,请为此数据库启用 Service Broker
昨晚遇到的这个问题,也知道Notifications service依赖底层的Service broker的.本以为只需要执行以下脚本对数据库启用Service broker即可. alter dat ...
- retry示例
#!/usr/bin/python2.7 # -*- coding: utf-8 -*- import time import exceptions def func(): # a,b = None ...
- docker 系列 - Dock高阶知识点文章汇集
docker 技术已经研究了一段时间, 基本的知识点和使用场景比较清楚了, 还有一些比较高阶的内容未曾尝试, 将来工作中如果能用到, 再深入研究吧. 这篇博文汇总了一些有用的文章链接. ======= ...
- 关于公众平台接口不再支持HTTP方式调用的公告
为保证数据传输安全,提高业务安全性,公众平台将不再支持HTTP方式调用.避免影响正常使用中含有HTTP方式调用的服务,请开发者尽快调整,将现有通过HTTP方式调用的切换成HTTPS调用,平台将于201 ...
- Tomcat下载,及环境变量配置
首先,介绍一下Tomcat: Tomcat是Apache 软件基金会(Apache Software Foundation)的Jakarta 项目中的一个核心项目,由Apache.Sun 和其他一些公 ...
- request和reponse