-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Description
Hi, guys, I used jemalloc as a memory allocator in my project recently. However, I found that there is a serious problem that dirty pages are not released in the multi-threaded usage scenario.
The conditions under which dirty pages are not released are as follows:
1.Thread A frees memory allocated by other threads;
2.Thread A did not apply for memory before freeing memory in step 1.
In order to confirm this problem, I read the source code of jemalloc. Finally I found out that under the above conditions arenas_tdata in tsd_tls always be NULL because arenas_tdata_bypass has been set true during first free.
This problem has been extended from adding the decay_time recycling version to the latest version.
Here is the demo code you can test :
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>
#define TEST_BUFF_MAX_NUM 2500
#define TEST_BUFF_SIZE 1090
void *g_test_buff;
void *test_leak_buff[TEST_BUFF_MAX_NUM];
void test_thread(void)
{
int i;
/*1st. free the memory allocated in other thread*/
if (g_test_buff)
{
free(g_test_buff);
}
/*2nd. here we go, malloc and free memory*/
while(1)
{
for (i = 0; i < TEST_BUFF_MAX_NUM; i++)
{
test_leak_buff[i] = malloc(TEST_BUFF_SIZE);
if (test_leak_buff[i] == NULL)
{
printf("malloc failed!\n");
while (1);/*just halt*/
}
memset(test_leak_buff[i], 0, TEST_BUFF_SIZE);
}
sleep(1);
for (i = 0; i < TEST_BUFF_MAX_NUM; i++)
{
free(test_leak_buff[i]);
}
}
}
int main(int argc, char **argv)
{
pthread_t tid;
g_test_buff = malloc(TEST_BUFF_SIZE);
if (g_test_buff == NULL)
{
printf("malloc failed.");
while(1);
}
if (pthread_create(&tid, NULL, (void*)test_thread, NULL) < 0)
{
printf("create test_thread failed.\n");
}
while (1)
{
sleep(1);
}
return 0;
}The following is the statistical result of the program running for a period of time :
decaying: time npages sweeps madvises purged
dirty: N/A 48115 0 0 0
muzzy: N/A 0 0 0 0
allocated nmalloc ndalloc nrequests
small: 3255048 158833 156241 159997
large: 57344 2 0 2
total: 3312392 158835 156241 159999