It took me many days and hours of efforts to narrow down on this. My application was consuming around 200 to 300 megabytes despite I was cleaning up everything. Finally I narrowed down that std::deque
was the reason.
Code snippet below demonstrates this.
Platform: Windows 8
Compiler: Visual Studio 2012
Here am just pushing structures to deque
and then poping them back and finally swapping it with blank deque to release memory fully (as suggested in answers of this or this)
#include <Psapi.h>
long long GetProcessPrivateBytes()
{
long long privatebytes;
HANDLE current_process;
PROCESS_MEMORY_COUNTERS_EX pmc;
current_process = GetCurrentProcess();
if (!GetProcessMemoryInfo(current_process, (PPROCESS_MEMORY_COUNTERS)&pmc, sizeof(pmc)))
{
return -1;
}
privatebytes = pmc.PrivateUsage;
return privatebytes ;
}
// Testing deque allocation
#define MYARRAY_SIZE 1024
#define MAX_ELEMENTS_IN_QUEUE (1024*1024)
struct MyStruct
{
unsigned char MyArray[MYARRAY_SIZE];
};
int _tmain(int argc, _TCHAR* argv[])
{
MyStruct mystruct;
std::queue<MyStruct> MyStructQueue;
while(1)
{
int MemoryConsumedByApplication = GetProcessPrivateBytes();
std::cout << "\n\nCurrent memory consumed by application " << (MemoryConsumedByApplication/1024)/1024 << " Megabytes";
if (MemoryConsumedByApplication > 128*1024*1014)
{
std::cout << "\nApplication still consuming too much memory. Press a key to quit the loop...";
_getch();
break;
}
std::cout << "\nFiling up queue with " << MAX_ELEMENTS_IN_QUEUE << " structs each of size " << MYARRAY_SIZE;
for (int i=0; i<MAX_ELEMENTS_IN_QUEUE; i++)
{
MyStructQueue.push(mystruct);
}
std::cout << "\nQueue filled up. Now poping back all elements...";
for (int i=0; i<MAX_ELEMENTS_IN_QUEUE; i++)
{
MyStructQueue.pop();
}
std::cout << "\nQueue poped back (Size " << MyStructQueue.size() << "). Now swaping with blank queue.";
std::queue<MyStruct>().swap(MyStructQueue);
}
std::cout << "\nPress a key to exit...";
_getch();
return 0;
}
The output of this code is:
Current memory consumed by application 0 Megabytes Filing up queue with 1048576 structs each of size 1024 Queue filled up. Now poping back all elements... Queue poped back (Size 0). Now swaping with blank queue. Current memory consumed by application 5 Megabytes Filing up queue with 1048576 structs each of size 1024 Queue filled up. Now poping back all elements... Queue poped back (Size 0). Now swaping with blank queue. Current memory consumed by application 5 Megabytes Filing up queue with 1048576 structs each of size 1024 Queue filled up. Now poping back all elements... Queue poped back (Size 0). Now swaping with blank queue. Current memory consumed by application 6 Megabytes Filing up queue with 1048576 structs each of size 1024 Queue filled up. Now poping back all elements... Queue poped back (Size 0). Now swaping with blank queue. Current memory consumed by application 5 Megabytes Filing up queue with 1048576 structs each of size 1024 Queue filled up. Now poping back all elements... Queue poped back (Size 0). Now swaping with blank queue. Current memory consumed by application 6 Megabytes Filing up queue with 1048576 structs each of size 1024 Queue filled up. Now poping back all elements... Queue poped back (Size 0). Now swaping with blank queue. Current memory consumed by application 6 Megabytes Filing up queue with 1048576 structs each of size 1024 Queue filled up. Now poping back all elements... Queue poped back (Size 0). Now swaping with blank queue. Current memory consumed by application 6 Megabytes Filing up queue with 1048576 structs each of size 1024 Queue filled up. Now poping back all elements... Queue poped back (Size 0). Now swaping with blank queue. Current memory consumed by application 6 Megabytes Filing up queue with 1048576 structs each of size 1024 Queue filled up. Now poping back all elements... Queue poped back (Size 0). Now swaping with blank queue. Current memory consumed by application 6 Megabytes Filing up queue with 1048576 structs each of size 1024 Queue filled up. Now poping back all elements... Queue poped back (Size 0). Now swaping with blank queue. Current memory consumed by application 6 Megabytes Filing up queue with 1048576 structs each of size 1024 Queue filled up. Now poping back all elements... Queue poped back (Size 0). Now swaping with blank queue. Current memory consumed by application 7 Megabytes Filing up queue with 1048576 structs each of size 1024 Queue filled up. Now poping back all elements... Queue poped back (Size 0). Now swaping with blank queue. Current memory consumed by application 7 Megabytes Filing up queue with 1048576 structs each of size 1024 Queue filled up. Now poping back all elements... Queue poped back (Size 0). Now swaping with blank queue. Current memory consumed by application 198 Megabytes Application still consuming too much memory. Press a key to quit the loop...
Thus, it can be seen that after few iterations application holds bulk amount of memory and since there is nothing other than std::deque
in the code, this memory must have been consumed by the std::deque
.
Any idea why this happens and how to make application completely free of any allocation?