Quantcast
Channel: Common Language Runtime Internals and Architecture forum
Viewing all articles
Browse latest Browse all 1710

Fatal Flaw in the Large Object Heap?

$
0
0

Hi All,

After playing with the GC I find the following interesting. The problem domain I typically work in requires the allocation of very large arrays for image processing. We have discovered some issues when our processes are long running. We run out of memory and can not reclaim it. Our only recouse is to restart our processes. In an effort to discover why I uncovered the following: The LOH (Large Object Heap) is never compacted. I think this is a fatal flaw in the GC. I understand MS stated reason for this, but shouldn't there be someway to compact the LOH if necessary, at least a method call that forces the issue?

Does anyone know of anything that can be done? Any workaround is better than killing the process...

Here is a demo program that shines a very bright light on the issue. If anyone sees anything wrong with the logic please respond.

Here is a typical run's output:

Pass: 1     Array Size (MB): 0910  0910
Pass: 1 Max Array Size (MB): 0920  0000 System Out of Memory...

Pass: 2     Array Size (MB): 0910  0910
Pass: 2 Max Array Size (MB): 0920  0000 System Out of Memory...

Pass: 3     Array Size (MB): 0010  0010
Pass: 3 Max Array Size (MB): 0020  0000 System Out of Memory...

Pass: 4     Array Size (MB): 0010  0010
Pass: 4 Max Array Size (MB): 0020  0000 System Out of Memory...

Pass: 5     Array Size (MB): 0010  0010
Pass: 5 Max Array Size (MB): 0020  0000 System Out of Memory...

Press any key to exit...

As you can see by the time the program is finished with the LOH you can't even get 20 MB allocated !!!! 

Here is the source code:

using System;
using System.Text;
using System.Threading;

namespace Burn_LOH
{
    class Program
    {
        static void Main (string[] args)
        {
            for (int count = 1; count <= 5; ++count)
                AllocBigMemoryBlock (count);
            Console.Write ("\nPress any key to exit...");
            while (Console.KeyAvailable == false)
                Thread.Sleep (250);
        }

        static void AllocBigMemoryBlock (int pass)
        {
            const int MB = 1024 * 1024;
            byte[] array = null;
            long maxmem = 0;
            int arraySize = 0;

            GC.Collect ();
            GC.WaitForPendingFinalizers ();
            while (true)
            {
                try
                {
                    arraySize += 10;
                    array = new byte[arraySize * MB];
                    array[arraySize * MB - 1] = 100;
                    GC.Collect ();
                    GC.WaitForPendingFinalizers ();
                    maxmem = GC.GetTotalMemory (true);
                    Console.Write ("Pass: {0}     Array Size (MB): {1:D4}  {2:D4}\r", pass, arraySize, Convert.ToInt32 (maxmem / MB));
                }
                catch (System.OutOfMemoryException)
                {
                    GC.Collect ();
                    GC.WaitForPendingFinalizers ();
                    maxmem = GC.GetTotalMemory (true);
                    Console.Write ("\n");
                    Console.Write ("Pass: {0} Max Array Size (MB): {1:D4}  {2:D4} {3}\r\n\n", pass, arraySize, Convert.ToInt32 (maxmem / MB), "System Out of Memory...");
                    break;
                }
                finally
                {
                    array = null;
                    GC.Collect ();
                    GC.WaitForPendingFinalizers ();
                }
            }
        }
    }
}


Viewing all articles
Browse latest Browse all 1710

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>