OutOfMemoryException – why?

Everybody knows OutOfMemory exception. As name says it is usually thrown when there is no more RAM on the computer, but it is not so clear as there are a few reasons why this exception can occur.

Possible reasons:
* There is no not allocated RAM memory on the computer – it means whole RAM installed on computer is used.
* Limit of the maximum allowed memory usage for a single .NET process is reached. It means that you still have free RAM to use, but single .NET process cannot use more. This limit depends on OS architecture.
* An huge (~2GB) object was trying to be allocated. Notice that .NET has a limit how big a single object can be.
* Too many threads are used in a single process. It means that plenty of RAM can be available, but limit for a number of threads is reached.

Further reading:
* http://stackoverflow.com/questions/13429129/task-vs-thread-differences
* http://stackoverflow.com/questions/13429129/task-vs-thread-differences
* https://support.microsoft.com/en-us/help/2020006/how-to-troubleshoot-out-of-memory-issues-system.outofmemoryexception-in-asp.net

See examples below. I show how some of these problems can be reproduced.

        /// <summary>
        /// Method starts threads one by one. Then there are more than 1000 threads it causes OutOfMemory exception (even when there is still not allocated memory available)
        /// </summary>
        private static void TooManyThreadsCauseOutOfMemory()
        {
            double value = 0;
            for (int i = 0; i <= 2000; i++)
            {
                Thread t = new Thread(() =>
                {
                    while (true)
                    {
                        value = new Random().NextDouble();
                        Thread.Sleep(10000);
                    }
                });
                t.Name = "My thread: " + i;
                t.Start();
            }
        }


        /// <summary>
        /// Opposite to threads, many tasks don't cause strange OutOfMemory exceptions. This can be solution for problem shown in example above.
        /// </summary>
        private static void ManyTasksDontCauseOutOfMemory()
        {
            double value = 0;
            Task.Factory.StartNew(() =>
            {
                while (true)
                {
                    value = new Random().NextDouble();
                    Thread.Sleep(10000);
                }
            }, TaskCreationOptions.None);
        }


        /// <summary>
        /// Many created objects cause out of memory exception, as there is a limit how much memory can be consumed by a single .NET process.
        /// In my environment when it reaches 1,5GB of memory, exception is thrown.
        /// Notice that I still have free RAM memory on my computer, but a single process has crossed its limit.
        /// </summary>
        private static void ManyObjectsCauseOutOfMemory()
        {
            var cummulativeCollection = new List<byte[]>();
            var sampleCollection = new byte[] { 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 };
            while (true)
            {
                cummulativeCollection.Add(sampleCollection);
            }
        }

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s