当前位置:

Linux 程序设计中由线程使用不当引起的内存泄露

2019-11-26  作者:炉石    阅读:2183

用 top 发现 virt 的使用量一直在涨,于是可以断定有内存泄露(也可以查看 /proc/<pid>/maps ,相应 pid 进程的 maps 文件中出现了很多内存碎片,也说明内存泄露)。经过排查,最终确定问题出现在多线程上。如图:






查询资料了解到: 


(1)Linux man page里是这样讲的:

 When a joinable thread terminates, its memory resources (thread descriptor and stack) are not deallocated until another thread performs pthread_join on it. Therefore, pthread_join must be called  once  for  each joinable thread created to avoid memory leaks.


当一个可结合线程终止时,它的内存资源(线程描述符和堆栈)就不会被释放,直到另一个线程在它上执行 pthread_join。因此,为了避免内存泄露,必须为每个可连接的线程调用 pthread_join




(2)《Linux高级编程》里是这样讲的:

可接合(非分离态的,需要等待)的线程,就像一个进程一样,当它执行结束时,并没有被GNU/Linux自动清理,而它的退出状态却仍在系统内挂着(这有点像僵尸进程),直到另一个线程调用pthread_join()获取其返回值时,其资源才被释放。




在 Linux 程序设计中,创建线程调用 pthread_create() 函数,该函数原型如下:


int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);


其中第二个参数 attr 为线程属性指针,一般情况下,我们创建线程时,若对线程属性没有特殊要求,都将此参数设为 NULL 。这也就使用了线程的默认属性 -- 非分离状态(joinable,亦可称为可结合状态)。之后,主线程必须在适当的时候调用 pthread_join() ,来结合(join,或等待,同步)子线程,同事释放线程本身占用的资源。否则,线程资源将驻留内存,直到整个进程退出为止,若进程会不断的创建线程,则每创建一次线程都会导致内存资源的消耗,很明显,这样就会构成内存泄露。





对于线程资源的释放,主要分为2类:


第一类,调用 pthread_join()




第二类,将线程属性设为分离状态(detached)


 1、 创建线程时,设置线程属性为分离线程


pthread_t t;

pthread_attr_t a; //线程属性

pthread_attr_init(&a);  //初始化线程属性

pthread_attr_setdetachstate(&a, PTHREAD_CREATE_DETACHED);      //设置线程属性

pthread_create( &t, &a, GetAndSaveAuthviewSDRStub, (void*)lp);                   //建立线程


2、在线程中将自己设为分离线程

pthread_detach(pthread_self())


————————————————

版权声明:本文为CSDN博主「linux_zhu」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/u011641885/article/details/78044188