在 LicheePI Zero 上做项目,应用程序使用了大量的线程实现耗时/异步操作的后台处理,发现一旦创建线程,使用 top 查看程序的内存占用情况就急剧升高。当对50个设备同时建立业务线程时,top 中的 VSZ 和 VSZ% 分别高达507m和1021%,同时查看 /proc/#pid/status 的VmRSS项(即占用的物理内存)时并没有明显变化,程序运行正常。但应用程序的 VSZ 过高总不是件好事,找到原因,再动手解决它。
VSZ 升高的原因
参考各位大侠的说明,VSZ 是多线程的应用程序在建立一个线程时所开辟的栈占用的虚拟内存空间所造成的,其缘由最终可追溯到 libc-2.11以后的版本对 pthread_create 的实现方法上[参见:pthread 线程 分配大小, top vsz 进程占用过大原因 - zzzxzzz - 博客园 (cnblogs.com)]。glibc-2.11以后的版本,在 pthread_create 函数中,为了防止各线程之间的内存竞争性冲突,都会为每一个线程开辟一块新的内存空间,使用的是 malloc 函数,其尺寸是 ulimit 指令所规定的当前 stack 的值(单位是kByte)。每创建一个线程,如果不设置线程堆栈的尺寸的话,VSZ都将升高一个默认堆栈尺寸。默认堆栈尺寸是 8MBytes,线程建立得多的时候,VSZ的数值就相当可观了。
LicheePI Zero 使用的 Linux 内核是 4.11.x以上版本,使用的 libc 是 2.23,大概率也是使用了上述方法。
设定线程堆栈尺寸的方法
C标准库中对线程堆栈(严格说来是”栈“而不是”堆“)的操作函数如下:
- int pthread_attr_getstacksize (const pthread_attr_t *__restrict&n

本文详细探讨了在LicheePIZero上运行多线程应用时遇到的VSZ(虚拟内存大小)过高的问题。分析了glibc从2.11版本开始,每个线程创建时默认分配的8MB栈空间导致VSZ急剧增长的原因。通过设置pthread线程属性,调整线程栈大小来控制VSZ,并提供了具体的代码示例。实验表明,通过设置合适的线程栈大小,并在程序启动前调整ulimit-s,可以有效抑制VSZ,同时确保程序稳定运行。
Zero 开发笔记(2):降低多线程程序的 VSZ&spm=1001.2101.3001.5002&articleId=126803967&d=1&t=3&u=17aaee845c5045edbde07e4d33419694)
801

被折叠的 条评论
为什么被折叠?



