• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 353
  • Last Modified:

MFC: how to give my application more memory

Dear experts,

I have an MFC application. A CMemoryException ("Not enough memory") is thrown at this line:
short* MonoBuff = new short[iSize];
iSize is 191,574,136.
Some time ago this application used to work, but many changes were made since then, so I don't know how to find what caused the problem. If iSize is 180,000,000, the exception is not thrown. Could you tell me please how I can give my application more memory, it is possible at all?
Thanks.
0
tantormedia
Asked:
tantormedia
1 Solution
 
Todd GerbertIT ConsultantCommented:
Install additional memory into your system is the first thing that comes to mind. Reconsider if it's really necessary to allocate 190 million short's at one shot is the next thing that comes to mind. And finally, while that seem excessive to me, I would kind of expect Windows should be able to pull that off with the help of swap, but perhaps you may find success using a private heap: http://msdn.microsoft.com/en-us/library/aa366711(v=VS.85).aspx
0
 
jhshuklaCommented:
Memory allocation success depends not only on the size of the request but also on the fragmentation of available memory. e.g. there might be 20 blocks of 9,000,000 bytes available but if they are scattered instead of being contiguous, your request would fail. Other reason is that you are truly out of memory.

From the limited information posted here, it is not possible to diagnose the problem.

1. Is this 32-bit or 64-bit application? 64-bit apps should not run out of memory.
2. Catch the exception, create breakpoint in catch. When the exception is caught and program pauses, open task manager and check memory usage. Is enough memory available?
3. Does it fail on first allocation or does it go through a few times and then fail?
0
 
jkrCommented:
Installing more memory won't help, a 32bit app always has only 2GB tops of address space available for allocation. You can try to determine the largest chunk of available memory before the allocation and not allocate if the size isn't sufficiant, e.g.
UINT unSizeAvail = HeapCompact(GetProcessHeap(),0); // will also perform some 'cleanup'

if (unSizeAvail > (iSize * sizeof(short) {

  short* MonoBuff = new short[iSize]; 
}

Open in new window

0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
tantormediaAuthor Commented:
Jkr,

I tried it, and unSizeAvail is only 278,528. It cannot even be compared to 190,000,000 * 2, and yet the program didn't throw any exceptions when iSize is 180,000,000. I cannot explain it.

Thanks.
0
 
tantormediaAuthor Commented:
jhshukla,

It is 32 bit application.
Enough memory is available on the machine.
It fails on first allocation of that size.
0
 
tantormediaAuthor Commented:
tgerbert,

Is it really possible to use private heap with MFC?

Thanks.
0
 
Todd GerbertIT ConsultantCommented:
Yes, you can use a private heap. You'll need to make sure you handle the lifetime of the heap - i.e. in addition to the short* you'll need somewhere to store the handle to the heap.

int count = 191574136;
int sizeRequired = count * sizeof(short);

// Create heap
HANDLE hHeap = HeapCreate(0, 0, 0); // initial size 0, with max size = 0 it will grow
	
if (hHeap)
{
	short *pMonoBuffer = NULL;

	// Allocate memory on private heap
	pMonoBuffer = (short *)HeapAlloc(hHeap, 0, sizeRequired);

	if (pMonoBuffer)
	{
		// use the array
		short val = -32768;
		for (int i = 0; i < count; i++)
			pMonoBuffer[i] = val++;

		// When done free the memory
		HeapFree(hHeap, 0, pMonoBuffer);

		// and destroy the heap
		HeapDestroy(hHeap);
	}
}

Open in new window


To be honest, I'm not sure why this would work and not your current method - it's a bit of a shot in the dark.  You might also consider setting the /3GB switch in boot.ini (on a 32-bit system this'll get you a 3GB addressable memory space).
0
 
sarabandeCommented:
private heap cannot be a solution. if you don't get 400 mb contiguous memory for an array from operation system why it should give you same amount or more for a private heap?

two ideas:

you might reserve the memory when the application was started. to this time you should get bigger chunks. so try in constructor of your application class to get the memory by

m_pMonoBuff = new short int[200000000];
assert(m_pMonoBuff != NULL);

Open in new window


where m_pMonoBuff is a member of your app class.

if that fails also (what i would expect) you should allocate smaller chunks like with

std::vector<std::vector<short int> > monoBuffVec(65536, std::vector<short int>(4096, 0));

Open in new window

what would give 64k * 4k shorts.

to access index idx you would do

short int si_at_idx = monoBuffVec[idx>>12][idx&0x0fff];

Open in new window

Sara
 

0
 
tantormediaAuthor Commented:
Thank you all who tried to help.
I decided to allocate the memory in pieces of 1,000,000 each and use them in a loop, freeing after each iteration. It worked.
0

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now