Pthread_create()和内存泄漏
pthread_create() and memory leaks
这个问题似乎被问了很多次。我有一些遗留的产品代码,看起来很好,直到它开始每天获得更多的连接。每个连接都会启动一个新线程。最终,它会耗尽内存并崩溃。
我要回到我多年没有处理过的pthread(和C套接字)。我的教程内容丰富,但当我使用top时,我也看到了同样的情况。所有线程都退出了,但是仍然占用了一些虚拟内存。Valgrind告诉我在调用pthread_create()时可能会丢失内存。下面是最基本的示例代码:
最可怕的部分是,当所有线程退出时,pthread_exit(NULL)似乎在VIRT中留下了大约100m的未计算空间。如果我把这行注释掉,它会更适合居住,但仍然有一些。在我的系统上,它以大约14k开始,以47k结束。
如果我将线程数增加到10,000,VIRT将增加到70+ gigs,但在50k左右结束,假设我注释掉pthread_exit(NULL)。如果我使用pthread_exit(NULL),它结束时大约113m仍然在VIRT中。这些可以接受吗?托普什么都没告诉我吗?
void* run_thread( void* id )
{
int thread_id = *(int*)id;
int count = 0;
while ( count < 10 ) {
sleep( 1 );
printf( "Thread %d at count %dn", thread_id, count++ );
}
pthread_exit( NULL );
return 0;
}
int main( int argc, char* argv[] )
{
sleep( 5 );
int thread_count = 0;
while( thread_count < 10 ) {
pthread_t my_thread;
if ( pthread_create( &my_thread, NULL, run_thread, (void*)&thread_count ) < 0 ) {
perror( "Error making thread...n" );
return 1;
}
pthread_detach( my_thread );
thread_count++;
sleep( 1 );
}
pthread_exit( 0 ); // added as per request
return 0;
}
我知道这是一个相当古老的问题,但我希望其他人能从中受益。这确实是一个内存泄漏。线程是用默认属性创建的。默认情况下,线程是可接合的。一个可接合的线程保持它的底层记账直到它完成。和加入。如果线程从未连接过,则设置Detached属性。一旦线程终止,所有(线程)资源将被释放。下面是一个例子:
pthread_attr_t attr;
pthread_t thread;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, 1);
pthread_create(&thread, &attr, &threadfunction, NULL);
pthread_attr_destroy(&attr);
在编辑将pthread_exit(0)
添加到main()
的末尾之前,您的程序将在所有线程完成运行之前完成执行。因此,valgrind
报告了在程序终止时仍然处于活动状态的线程仍然持有的资源,使其看起来像您的程序有内存泄漏。
在main()
中调用pthread_exit(0)
使主线程在自己退出之前等待所有其他派生线程退出。这可以让valgrind
在内存利用率方面观察到干净的运行。
(我假设下面linux是您的操作系统,但从您的评论中可以看出您正在运行各种UNIX)
你看到的额外的虚拟内存只是linux分配给你的程序的一些页面,因为它是一个大的内存用户。当您到达空闲状态时,只要您的驻留内存利用率很低且恒定,并且虚拟利用率相对恒定,您就可以假设您的系统运行良好。
默认情况下,linux上每个线程获得2MB的堆栈空间。如果每个线程堆栈不需要那么多空间,您可以通过初始化pthread_attr_t
并使用pthread_attr_setstacksize()
将其设置为较小的堆栈大小来调整它。合适的堆栈大小取决于函数调用堆栈增长的深度以及这些函数的局部变量占用的空间大小。
#define SMALLEST_STACKSZ PTHREAD_STACK_MIN
#define SMALL_STACK (24*1024)
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setstacksize(&attr, SMALL_STACK);
/* ... */
pthread_create(&my_thread, &attr, run_thread, (void *)thread_count);
/* ... */
pthread_attr_destroy(&attr);
- 从构造函数抛出异常时如何克服内存泄漏
- malloc() 可能出现内存泄漏
- 这个极客对极客的trie实现是否存在内存泄漏问题
- 尽管遵循了规则,内存泄漏在哪里
- 为什么调用堆栈数组会导致内存泄漏
- 在简单示例中,Python3 + ctypes 回调会导致内存泄漏
- 使用模板类的自定义列表类型中的内存泄漏
- 为什么以下C++代码中存在内存泄漏?
- OpenCV 我应该使用智能指针来防止内存泄漏吗?
- 我是否生成线程并导致内存泄漏?
- 多线程程序中出现意外的内存泄漏
- 为什么此函数会导致内存泄漏?
- 在 C++ 库中使用cythonized python时内存泄漏
- 需要帮助查找内存泄漏
- 瓦尔格林德的内存泄漏使用新的
- 无法找出我的代码中的内存泄漏
- C++ 结构内部的unordered_map会导致内存泄漏问题吗?
- 可视化 使用 VS Code 查找C++应用程序中的内存泄漏
- Shared_ptr双链接列表内存泄漏
- C++ 在类中使用常量引用文本时 O2 内存泄漏