您的位置:首页 > 其它

解决设备应用程序无法申请到内存,导致设备无法正常工作的问题---优化设备虚拟内存使用

2016-12-13 16:29 926 查看

优化设备虚拟内存使用

前段时间运维的同事反馈我们的设备升级到最新版本使用几天后就无法正常使用了,重启设备后又能正常使用几天,然后继续出现问题。当时查看故障设备的运行日志发现有大量的“no buffer space available“错误日志。这个日志是我们设备上两个进程之间socket通信的错误日志。正好这次的新版本优化了这两个进程,所以当时最先想到的就是这个故障是这次优化导致的。

对照这条错误日志找到相应的socket,该socket在两个进程之间通信机制如下图:



日志中的报错信息就是由上图进程2中的Read Resopne引起的,刚开始的第一想法就是进程2写的速度大于进程1读的速度,导致buffer被写满了。但是在阅读了系统的socket代码,如果是上述猜测的话报错的应该是pipe break;而且重启进程应该能恢复,但是实际上故障重现时,重启该进程错误仍然存在。
重新查看系统的运行状况,使用TOP命令时发现系统中有一个进程的虚拟内存达到了500多M,而真实的物理内存只有1G。查看proc/meminfo,



CommitLimit为508124,对照上面的TOP结果大概明白了问题原因,系统overcommit_memory参数为0,
overcommit_ratio 为50,当有应用申请的内存到500M时,再有其他程序申请内存时,虽然物理内存仍然还有剩余空间,但是系统仍然不在为该应用申请内存了,所以导致socket报“no
buffer space available“的错误。
所以系统存在两个问题:



1.overcommit_ratio配置的比较小,将overcommit_ratio配置70(也可以将overcommit_memory修改为2,这样只要有物理内存在,系统就不在检查虚拟内存)
2.进程是否有虚拟内存泄漏的问题
花了点时间检查进程为什么虚拟内存为那么高,通过/proc/pid/maps查看该进程的内存使用情况,发现虚拟内存暂用过高的原因是,该进程是一个SERVER-CLENT应用的SERVER端,当有CLINET来连的时候它就会pthread_create
一个线程,没个线程会有一个默认为8M的栈空间(通过/proc/pid/maps可以看到),但是这个栈空间实际没有使用,所以没有占用实际内存,只是占用了虚拟内存。解决方案就是将8M的栈空间改为500K
unsigned stacksize = 524288;//500K
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setstacksize(&attr, stacksize);

if(pthread_create(newThread, &attr, threadFunc, arg) != 0) {
return CWErrorRaise(CW_ERROR_NEED_RESOURCE, "Can't create thread (maybe there are too many other threads)");
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐