Unmanaged Heap Size of .net application

3.9k Views Asked by At

I'm currently trying to do memory analysis on a C# project I am working on to determine if there any leaks since this application needs to have as close to 100% up-time as possible. I started using the Ants Memory Profiler version 7.4, and noticed that my unmanaged memory was growing continuously over time even though my managed memory was not.

After more experimenting, I tried doing a similar analysis on a program that does nothing but block on a Console.ReadLine() instruction. I ran the analysis and noticed the same thing happening. My unmanaged heap was slowly growing. In fact, it actually only seemed to grow as the garbage collector was being called (by the snapshot functionality). Now why would calling garbage collect repeatedly lead to an un-endable increase in unmanaged memory? Was it something to do with ANTS?

I would like to use some other tool, preferably something like windbg or SOS to determine what it sees my unmanaged memory usage is. It is not important right now for me to know what is in it -- although this may help for debugging in the long run. I'm simply trying to determine the unmanaged memory usage of an application currently running. I would like to see if this is really an issue with ants or a misunderstanding by me of how the environment works. Having some sort of .net, visual studio, or windows tool to give me accurate information about my process would help me with this.

3

There are 3 best solutions below

8
Cole Tobin On

System.GC.GetTotalMemory(bool) might be what you are looking for. Here is the annotated example from the link:

using System;
namespace GCCollectIntExample
{
    class MyGCCollectClass
    {
        private const long maxGarbage = 1000;
        static void Main()
        {
            MyGCCollectClass myGCCol = new MyGCCollectClass();

            // Determine the maximum number of generations the system 
        // garbage collector currently supports.
            Console.WriteLine("The highest generation is {0}", GC.MaxGeneration);

            myGCCol.MakeSomeGarbage();

            // Determine which generation myGCCol object is stored in.
            Console.WriteLine("Generation: {0}", GC.GetGeneration(myGCCol));

            // Determine the best available approximation of the number  
            // of bytes currently allocated in managed memory.
            Console.WriteLine("Total Memory: {0}", GC.GetTotalMemory(false));

            // Perform a collection of generation 0 only.
            GC.Collect(0);

            // Determine which generation myGCCol object is stored in.
            Console.WriteLine("Generation: {0}", GC.GetGeneration(myGCCol));

            Console.WriteLine("Total Memory: {0}", GC.GetTotalMemory(false));

            // Perform a collection of all generations up to and including 2.
            GC.Collect(2);

            // Determine which generation myGCCol object is stored in.
            Console.WriteLine("Generation: {0}", GC.GetGeneration(myGCCol));
            Console.WriteLine("Total Memory: {0}", GC.GetTotalMemory(false));
            Console.Read();
        }

        void MakeSomeGarbage()
        {
            Version vt;

            for(int i = 0; i < maxGarbage; i++)
            {
                // Create objects and release them to fill up memory 
                // with unused objects.
               vt = new Version();
            }
        }
    }
}
1
RollRoll On

use garbagge collector profiler. in case there are more objects on bucket 2 and 3 than 1 then you are not managing your unmanaged resources correctly

1
plinth On

AQTime from SmartBear does a pretty good job giving you memory analysis on both managed and unmanaged code. A lot of my work is in the managed and unmananged boundary and I've used it multiple times to find memory leaks.

If you're working with large blocks of unmanaged memory, be sure to call GC.AddMemoryPressure and GC.RemoveMemoryPressure to help the GC along.