Linux 程序设计中由线程使用不当引起的内存泄露
来源:互联网 发布:鼠标质量排行 知乎 编辑:程序博客网 时间:2024/06/05 17:41
用 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())
- Linux 程序设计中由线程使用不当引起的内存泄露
- Linux程序设计中由线程使用不当引起的内存泄漏
- 检测由new/delete使用不当引起的内存泄露
- 检测由new/delete使用不当引起的内存泄露
- Android中Handler使用不当引起的内存泄露
- Android中Handler使用不当导致内存泄露的问题
- Android性能优化(三)——Handler使用不当引起的内存泄露
- ABMultiValueCopyLabelAtIndex使用不当引起的内存泄漏
- ABMultiValueCopyLabelAtIndex使用不当引起的内存泄漏
- Hashset 使用不当引起的内存泄漏
- 由dispatch_async引起的内存泄露
- Linux-pthread_create使用不当可能导致内存泄露
- Android如何避免由Context引起的内存泄露
- Android 中 Handler 引起的内存泄露
- Android 中 Handler 引起的内存泄露
- Android中Handler引起的内存泄露
- Android中Handler引起的内存泄露
- Android中Handler引起的内存泄露
- 抽象类和接口的区别
- touch事件解析
- Linux GPIO 的注册与申请
- 纵向的ListView或RecyclerView点击都可以让item跳到中间(类似TabLayout的滑动)
- ActiveMQ系列—ActiveMQ性能优化(中2)(处理规则和优化)
- Linux 程序设计中由线程使用不当引起的内存泄露
- Oracle 中数据类型变更无效 ---ora-22858:数据类型的变更无效 for clod
- 2017研究生数学建模题
- java 链接IBM MQ的问题
- 虚拟防火墙实验
- unity shader:初探纹理
- Docker开源容器运行时组件Containerd
- 【Bash百宝箱】doxygen
- Qt在控件未显示时如何获取正确的控件尺寸