Linux 多线程应用 降低内存(VSZ)占用(嵌入式)

2021/6/16 7:22:58

本文主要是介绍Linux 多线程应用 降低内存(VSZ)占用(嵌入式),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

嵌入式开发的内存无疑是非常吃紧的。特别是一些老设备(512MB内存),之前的一台终端设备因为内存占用过高,出现了运行出错,进程管理的APP直接杀死了占用最高的媒体APP,导致视频输出出现异常。
于是进探索了内存优化之路。在确保长时间运行内存不会增加(没有内存泄漏)后,首先查看 /proc 下的进程 内存占用的smap 信息:

cat /proc/<pid>/smaps|grep -v ' 0 kB'

查看进程申请的内存详情
通过观察不难发现大量的内存占用都在栈上。由于这个APP是一个多线程进程,一个线程就有一个栈,导致了进程申请的内存大量被用于线程栈的申请上,每个栈8MB,仅10个线程就占用了100MB的虚拟内存空间。
stack mem
一个进程占用99MB内存,11个线程栈的内存占了88MB。那么方向就很明确了。减少栈的大小即可。
首先想到的是,直接进行全局的配置系统默认栈得大小,因为目前Linux程序的线程使用的都是默认的参数,即采用系统默认的栈大小进行开辟线程的栈。使用ulimit -s 指令在启动脚本加入:

ulimit -s 1024

以上就将系统默认栈设置为1024KB,单位是KB。启动系统,不巧的是,有些APP运行出现了异常,猜测界面APP使用了大量的变量,导致栈的溢出,APP直接就退出了。缩小系统栈还是有一定的风险,而且不知会不会引入其他的问题。
想着既然Linux系统一般都是使用pthread启动线程,而且子线程一般变量较少,不需要很大的栈空间,那么我们可以通过pthread_create的pthread_attr_t进行参数的设定设定进程生成的线程栈,达到缩小进程内存占用的目的。
将佘艳的线程生成

int thread::startThread(callable *c) {

	int const res = pthread_create(&handle_, 0, &posix_thread_proxy, static_cast<void*>(c));
	if (res != 0) {
		delete c;
		return -1;
	}

	return 0;
}

改为这样创建线程(这里的stacksize的单位是字节)

int thread::startThread(callable *c) {

	pthread_attr_t thread_attr;
	pthread_attr_init(&thread_attr);
	pthread_attr_setstacksize(&thread_attr, 1024*1024); ///< 1MB
	int const res = pthread_create(&handle_, &thread_attr, &posix_thread_proxy, static_cast<void*>(c));
	if (res != 0) {
		delete c;
		return -1;
	}
	pthread_attr_destroy(&thread_attr);

	return 0;
}

即可将原来的8MB栈大小改为1MB,效果显著。

top指令查看 左边为修改前,右侧为修改后
top
ps -o pid,comm,rss,vsz 指令查看 左边为修改前,右侧为修改后
ps
可以看到线程多的APP占用基本缩小了一半多。



这篇关于Linux 多线程应用 降低内存(VSZ)占用(嵌入式)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程