Bug 27976 - When the last heap in the user process into the non-main area has memory in use, even if the previous heap is already free, the previous heap will not be released
Summary: When the last heap in the user process into the non-main area has memory in u...
Status: UNCONFIRMED
Alias: None
Product: glibc
Classification: Unclassified
Component: malloc (show other bugs)
Version: 2.33
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2021-06-10 10:03 UTC by liudongyun
Modified: 2021-06-15 01:34 UTC (History)
0 users

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments
my idea (17.85 KB, image/png)
2021-06-10 10:45 UTC, liudongyun
Details

Note You need to log in before you can comment on or make changes to this bug.
Description liudongyun 2021-06-10 10:03:21 UTC
bug:The system has a total of 32G memory. When the last heap in the user process into the non-main area has memory in use, even if the previous heap is already free, the previous heap will not be released, resulting in the memory cache reaching 20G.


for example:
I create a new thread and malloc(2000Bytes), the thread will attached to non-main-arena.I trim the heap->size = 512*1024 befor test ,then run the follow code. we can see the pLast not free,then the non-main-arena memory not free .This may cause the memory cached in the non-main-area to be unusable after the memory usage reaches its peak, and even most of the memory of the entire system can be cached.When the last pLast of memory is released, most of the memory in the entire non-main-area will be released to the system.

I tried to solve this problem by checking to release the heap that the current chunk belongs to and unmmaped if it is all free.The method has achieved good results.
---------------------------------------------------
void *pLast = NULL;
void  *free_last()
{
	free(pLast);
	return NULL;
}
void func1()
{
	void *pp[10240];
	int i = 0;
	
	for(i=0;i<10230;i++){
		 
		pp[i] = malloc(2048);
		memset(pp[i], 0, 2048);
	}
	
	pLast = malloc(2048);
	printf("pLast == %p     \n",pLast);
	memset(pLast, 0, 2048);
	
	for(i=0;i<10230;i++)
      free(pp[i]);
  
     printf("finish  malloc free \n");
	
}

int main()
{
	int i = 0;
	void *p = NULL;
	pthread_t  tid;
	p = malloc(1024);
	memset(p, 0, 1024);
	pthread_create(&tid, NULL, func1, NULL);

	while(1)
	{
		i++;
		sleep(10);
	}

	free_last();

}
---------------------------------------------------
Comment 1 liudongyun 2021-06-10 10:45:43 UTC
Created attachment 13490 [details]
my idea

When the user calls the free function, check whether the heap where the current chunk is located is free, and if so, release the entire heap