Linux/C++:线程结束时内存未完全释放



英特尔i7 上的Ubuntu 18.04

以下代码按顺序启动5个线程,然后在退出前休眠60秒。每个线程通过malloc分配1MB内存,然后立即释放,然后休眠10秒,然后返回。

当线程结束时,人们认为内存将完全释放给操作系统。Top和/proc/(pid(/smaps都显示,线程返回后,内存仍然保留给main,不可用于同一台计算机上运行的其他进程。

这是正常行为吗?

#include <iostream>
#include <pthread.h>
#include <limits.h>
#include <unistd.h>
#define HOWMANY 5 
void* threadFct(void*);
int main()
{
int threadCounter;
pthread_t tId;
threadCounter = 0;
while(threadCounter < HOWMANY)
{
sleep(1);
std::cerr << "THREAD " << std::hex << pthread_self() << " creating thread " << std::dec << threadCounter << std::endl;
int error = pthread_create(&tId, NULL, threadFct, NULL);
threadCounter++;
if (error == 0)
pthread_detach(tId);
}
sleep(60);
}
void* threadFct(void*)
{
uint32_t dim = 1024*1024;
char *buff = (char*)malloc(dim);
if (buff != NULL)
{
std::cerr << "THREAD " << std::hex << pthread_self() << " got memory at address " << (void*) buff << " filling buffer... ";
for (int i = 0; i < dim; i++)
buff[i] = (char)(rand() % 256);
std::cerr << "done" << std::endl;
}
else
std::cerr << "THREAD " << std::hex << pthread_self() << " malloc failed" << std::endl;
if (buff != NULL) free(buff);
sleep(10);
std::cerr << "THREAD " << std::hex << pthread_self() << " exiting" << std::endl;
pthread_exit(NULL);
}```

简而言之,每个进程都有一个内存的虚拟视图并使用它,进程有一个堆栈内存和堆内存,我们可以使用malloc()等函数或直接使用sbrk()等函数来更改堆的大小。当我们请求一块内存时,堆的大小会变大。

让我们想象一下,这是一个进程堆内存,每个线程都使用了其中的一兆字节:

Heap
+------
|  +----------+----------+----------+----------+----------+
|  | thread_1 | thread_2 | thread_3 | thread_4 | thread_5 |
+----------+----------+----------+----------+----------+
1MB         1MB        1MB       1MB         1MB

所以,在这里,如果thread_2完成了它的工作,并且它准备终止,那么它在堆上分配的内存会发生什么?这取决于进程是否需要再次在堆上分配另外1MB,使用thread_2释放的内存;但如果进程请求更多,堆大小就会变大:

Heap
+------
|  +----------+----------+----------+----------+----------+------------+
|  | thread_1 | ???????? | thread_3 | thread_4 | thread_5 | for_others |
+----------+----------+----------+----------+----------+------------+
1MB         1MB        1MB       1MB         1MB        3MB

进程中销毁的内存将被释放并可用于操作系统。


我认为这些可能很有用:

  • https://danluu.com/malloc-tutorial/
  • https://man7.org/tlpi/

最新更新