简体   繁体   中英

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

Ubuntu 18.04 on an Intel i7

The following code starts 5 threads in sequence, then sleeps 60 seconds before quitting. Each thread allocates 1 MB memory via malloc, then frees it immediately, then sleeps 10 seconds then returns.

When the threads end one thinks that the memory would be fully released to the OS. Top and /proc/(pid)/smaps both show that after the threads return, the memory is still reserved to main and not available for other processes running on the same computer.

Is that normal behaviour?

#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);
}```

In a nutshell, every process have a virtual view of memory and work with it, process have a stack memory and heap memory and we can change size of heap with functions like malloc() or directly using functions like sbrk() . When we request a block of memory the size of heap get larger.

Let's imagine this is your process heap memory which every thread used one megabyte of it:

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

So here if thread_2 done it's job and it's ready to terminate, what is happen for it's allocated memory on heap? It's depend on if process need again to allocate another 1MB on the heap, the thread_2 released memory is use; but if process request more, the heap size get larger:

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

On process destruction memory will be freed and available to OS.


I think these could be useful:

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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