Linux 程序设计中由线程使用不当引起的内存泄露
2017-09-20 18:53
537 查看
用 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())
查询资料了解到:
(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())
相关文章推荐
- Linux程序设计中由线程使用不当引起的内存泄漏
- 检测由new/delete使用不当引起的内存泄露
- Android中Handler使用不当引起的内存泄露
- Android性能优化(三)——Handler使用不当引起的内存泄露
- 检测由new/delete使用不当引起的内存泄露
- 在linux下使用valgrind检查wireshark的内存泄露情况
- Java线程引起的内存泄露问题浅析
- Android中Handler使用不当导致内存泄露的问题
- CreateThread 使用不当引起内在泄露? CreateThread 和 _beginthreadex 区别
- Linux 内核内存泄露工具使用
- C++ string 使用引起的内存泄露
- 记一次指针使用不当造成的内存泄露。
- linux 线程的同步 三 (内存信号量的使用)
- 使用AndroidStudio分析和解决ImageLoader引起内存泄露问题
- linux使用valgrind 工具检查内存泄露
- Linux下正确使用getifaddrs()函数避免内存泄露
- linux 下内存泄露检测工具valgrind的使用
- CreateThread 使用不当引起内在泄露? CreateThread 和 _beginthreadex 区别。
- Valgrind 的使用,找出linux的内存泄露和内存越界。
- Context 使用不当造成内存泄露