locked
Why do I get OutOfMemoryException? RRS feed

  • Question

  • Why do I get OutOfMemoryException running the following code?

    m_lst = gcnew System::Collections::Generic::List<array<double>^>;
    for(int i=0; i<10; i++)
    {
          m_lst->Add( gcnew array<double>(512*512*100) );
    }

    (Create a WinForm app and insert this code at the end of InitializeComponents)

    I got the exception when i=5. (that is only ~1GB of memory).

    I know that is a lot of memory, but my computer has 2.5GB of RAM and the page size is set to 4GB.

    I have no other apps running.

    The Windows Task Manager shows vailable physical memory of 2096000K.

    I am run VS2005 Pro and WinXP Pro.

    Please help.  Thank you.

    Friday, May 19, 2006 4:56 PM

Answers

  • First is that the chance to allocate 10 arrays of that kind is very small. Each array needs 200 megabytes of memory and 10 of them means 2 gigabyte.  No matter how much physical memory you have on the machine a 32 bit application we'll have a 2 gigabyte virtual address space but this space is also used for other things than allocating memory. EXE/DLL are loaded in it and the threads stacks are allocated from it for example. You may try configure the system to give you 3 GB of address space but I'm not sure if .NET can take advantage of it and some other apps and drivers my fail in this configuration. For some steps on how to enable 3 GB address space you can see for example this article:

    http://www.microsoft.com/technet/prodtechnol/exchange/guides/E2k3Perf_ScalGuide/e834e9c7-708c-43bf-b877-e14ae443ecbf.mspx?mfr=true

    As for why it fails just after 5 allocations that may have to do with memory fragmentation. After allocations/reallocations and because of other memory allocations (like loaded DLLs) you may end up with 1 gigabyte of free memory but fragmented into pieces of 100 megabytes for example and obviously in that case the memory allocation will fail. It's true that the .NET garbage collector can move objects in memory to "defragment" memory but it does this only for small objects (I think under ~ 80k).

     

    Friday, May 19, 2006 6:57 PM

All replies

  • Hmm... do you use a 64 bit system or a 32 bit one ?
    Friday, May 19, 2006 5:53 PM
  • 32 bit
    Friday, May 19, 2006 6:06 PM
  • First is that the chance to allocate 10 arrays of that kind is very small. Each array needs 200 megabytes of memory and 10 of them means 2 gigabyte.  No matter how much physical memory you have on the machine a 32 bit application we'll have a 2 gigabyte virtual address space but this space is also used for other things than allocating memory. EXE/DLL are loaded in it and the threads stacks are allocated from it for example. You may try configure the system to give you 3 GB of address space but I'm not sure if .NET can take advantage of it and some other apps and drivers my fail in this configuration. For some steps on how to enable 3 GB address space you can see for example this article:

    http://www.microsoft.com/technet/prodtechnol/exchange/guides/E2k3Perf_ScalGuide/e834e9c7-708c-43bf-b877-e14ae443ecbf.mspx?mfr=true

    As for why it fails just after 5 allocations that may have to do with memory fragmentation. After allocations/reallocations and because of other memory allocations (like loaded DLLs) you may end up with 1 gigabyte of free memory but fragmented into pieces of 100 megabytes for example and obviously in that case the memory allocation will fail. It's true that the .NET garbage collector can move objects in memory to "defragment" memory but it does this only for small objects (I think under ~ 80k).

     

    Friday, May 19, 2006 6:57 PM
  • Thanks for your reply.

    I always thought that .NET GC will take care of memory defragmentation.  I can understand that moving a large chunk of memory does affect system performance, but it's still much better than just crash the app while the system still have enough memory.

    Is there anyway to defragment memory (programmatically)?

    Thanks.

    Friday, May 19, 2006 7:56 PM