繁体   English   中英

Linux / C++:memory 在线程结束时未完全释放

[英]Linux / C++ : memory is not fully released when threads end

英特尔 i7 上的 Ubuntu 18.04

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

当线程结束时,人们认为 memory 将完全释放到操作系统。 top 和 /proc/(pid)/smaps 都显示,在线程返回后,memory 仍然保留给 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);
}```

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

让我们假设这是您的进程堆 memory 每个线程使用它的一兆字节:

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

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

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

在进程破坏时 memory 将被释放并可供操作系统使用。


我认为这些可能有用:

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM