views:

260

answers:

3

Hi, guys, My system is Windows XP. Virtual Size displayed in TaskManager is different with MEMORYSTATUSEX.ullAvailVirtual got from GlobalMemoryStatusEx.

When I create lot of buffers and the memory usage is up, MEMORYSTATUSEX.ullAvailVirtual can well reflected the virtual size usage. It's same.

But when I delete the memory, Virtual Size in task manager is down, but MEMORYSTATUSEX.ullAvailVirtual is still very small. I don't know why....

I am totally confused.

A: 

You could be suffering from memory fragmentation. (I.e. if you lea a few bytes between each large allocation, it effectively forces up the virtual bytes of your application).

You might find it more reliable to compare figures against perfmon - the counters I've always used in the past have been Private bytes (memory actually allocated) and Virtual bytes (memory address space allocated) - if those two counters diverge, then you have a memory fragmentation problem, which will be the result of a memory leak. The figures in Task Manager, whilst true and accurate, don't convey anything particularly useful.

Rowland Shaw
A: 

MEMORYSTATUSEX.ullAvailVirtual reports unreserved and uncommited memory in the user mode portion of the process.

So you need to do a VirtualFree to unreserve/decommit that memory. Doing a C++ new/delete does not guarantee a VirtualAlloc/VirtualFree call, and that would explain why the value has not changed significantly.

Moron
Because what I can see is the address via new and delete, how to call VirtualFree to unreserved memory?delete buffer; VirtualFree( buffer )?
Buzz
No. It is not easily put in the programmers' control. To gain more control, you either need to use placement new, or find some implementation of new/delete which allows you to do that, as part of the contract.Why do you even care about this, though?
Moron
I met a problem that when my process seized Virtual Size about 1.5GB, new char[1MB] would fail. I don't know why and suspect it's due to memory fragment, because I think there should be enough virtual space for additional malloc. My system is XP 32bit, and TaskMonitor reports that Memory Usage is 1.571GB and Virtual Size is 1.614GB. What's the best way to check the root cause ... I find debug memory allocation issue in some extreme case is a very complex and effort consuming work..
Buzz
Another thing I want to mention is that the range of buffer allocation size is very different. The buffer is used to store vertex buffer in Computer Graphics. Some is tiny about tens of kilo bytes, some are above 2MB.
Buzz
It is probably fragmentation. You could try allocating all the memory first, by creating all the vertex buffers first, instead of deletes interspersed between the news.
Moron
Thanks. To avoid deletes between news is a nice way. But the buffer which would used to be rendering is very large. That would more more than 4GB.
Buzz
A: 

When you delete allocated memory, the OS doesn't immediately return that memory but keeps it reserved for the process, at least until another process needs that memory. This improves the performance, because the very same process might need the just deleted memory a few ms later again.

To really free the deleted memory, you can call

SetProcessWorkingSetSize(GetCurrentProcess(), (SIZE_T)-1, (SIZE_T)-1);

Maybe that will force GlobalMemoryStatusEx() to return the values you expect?

Stefan
Thanks. I am not sure if I will try it, since it seems a system impact.I will have a try of TBB allocator. I find the its allocation speed is faster than CRT default new. It looks distinctive in large amount of memory allocation.
Buzz