views:

533

answers:

5

Hi,

My Windows/C++ application allocates ~1Gb of data in memory with the new operator and processes this data. The data is deleted after processing.

I noticed that if I run the processing again without exiting the application, the second call to "new" operator to allocate ~1gb of data fails.

I would expect Windows to deliver back the memory again. Could this be managed in a better way with some other win32 calls etc. ?

Thanks,

Paul

+6  A: 

I don't think this is a Windows problem. Check if you used delete or delete[] correctly. Perhaps it would help if you post the code that is allocating/freeing the memory.

schnaader
+3  A: 

This could be due to memory fragmentation (in reality, address space fragmentation), where various factors have contributed to your program address space not having a 1gb contiguous hole available. In reality, I suspect a bug in your memory management (sorry) - have you run your code through leak detection?

Adam Wright
I have made sure that each new'ed pointer is delete'd as well. My debug print logs show this at least.Are there any tools within VS2003 or standalone to help me look for leaks ?
Paul Baumer
Have a read of http://msdn.microsoft.com/en-us/library/x98tx3cf(VS.80).aspx , which might help. You should also check that any objects you're new'ing that allocate resources must deallocate in their destructors, and that any new[] is matched with delete[].
Adam Wright
I was thinking that delete[] is obsolete and delete is sufficient.
Paul Baumer
delete[] is required whenever you use new[] to allocate data.
e.James
Yes, not using delete[] is most likely to be your problem. I should have made that more clear in my answer, I guess.
schnaader
Memory fragmentation: In 32-bit windows, aren't you restricted to a 4gig memory address space? Or is it 2gig? If you are trying to allocate ~1gb, wouldn't that require a ~1gb CONTIGUOUS memory block... So anything else allocated after delete[] would cause memory fragmentation...
Mr.Ree
It may also be an idea to call the CRT function '_heapmin' prior to the call to 'new': "The _heapmin function minimizes the heap by releasing unused heap memory to the operating system."
Stefan Rådström
+3  A: 

In most runtime environments memory allocated to an application from the operating system remains in the application, and is seldom returned back to the operating system. Freeing a memory block allows you to reuse the block from within the application, but does not free it to the operating system to make it available to other applications.

Microsoft's C runtime library tries to return memory back to the operating system by having _heapmin_region call _heap_free_region or _free_partial_region which call VirtualFree to release data to the operating system. However, if whole pages in the corresponding region are not empty, then they will not be freed. A common cause of this is the bookkeeping information and storage caching of C++ containers.

Diomidis Spinellis
This might be the case for Java, but is certainly not the case for Windows standard C/C++ libraries, at least not for anything larger than a memory page. Give it a try and see it yourself.
DrJokepu
You're right. I've edited the answer to describe how Microsoft C handles deallocation.
Diomidis Spinellis
+1  A: 

Since you are using very large memory blocks, you should consider using VirtualAlloc() and VirtualFree(), as they allow you to allocate and free pages directly, without the overhead (in memory and time) of interacting with a heap manager.

Since you are using C++, it is worth noting that you can construct C++ objects in the memory you allocate this way by using placement new.

Matthew Xavier
+1  A: 

This problem is almost certainly memory fragmentation. On 32 bit Windows the largest contiguous region you can allocate is about 1.1GB (because various DLLs in your EXE preventa larger contiguous range being available). If after deallocating a memory allocation (or a DLL load, or a memory mapped file) ends up in the middle of your previous 1GB region then there will no longer be a 1GB region available for your next call to new to allocate 1GB. Thus it will fail.

You can visualize this process using VM Validator.

Stephen Kellett