none
C# Stack and Heap contents? RRS feed

  • Question

  • Hi
    1. Is there function(s) that can assist in viewing (listing) the current contents within the Stack or within the Heap?
    2. Is there function(s) that can monitor the allocated and used size of the Stack?
    3. Likewise, Is there function(s) that can monitor the allocated and used size of the Heap?

    Thanks

    Thursday, September 3, 2009 2:54 PM

Answers

  • You can use the microsoft debuggers like windbg or cdb to analyse the heap and stack of a .net application along with .net performance counters. In order to look at the managed structures in windbg or cdb you have to load the SOS dll which is part of the Framework. Using commands like "!dumpheap -stat" or "!dumpstack" you can look at the objects in the heap or stack. You can set break points and also look at the effect of different operations in your code. The allocated size can of all the GC heaps (gen0, 1, 2 and the large object heap)  can be monitored using the .net performance counters installed by default with the framework.
    Thursday, September 3, 2009 4:26 PM

All replies

  • You might check out the System.Diagnostics namespace.  I'm not sure if everything you want is there, but you can generate a stack trace using the StackTrace class there.
    Tom Shelton
    Thursday, September 3, 2009 3:33 PM
  • Note that the StackTrace class can give you different results based on whether you've built to debug or release.  In other words, I don't trust it.  GC.GetTotalMemory can give you an estimation on the used size of the heap, but it isn't perfect.  Classes that are wrappers around unmanaged code might be extremely small in the heap, but wrap a really huge unmanaged chunk of data... like the Bitmap class. 

    Jeff, if you're having a specific problem with memory management, we could probably help track it down, but as for doing the things you're trying to do within managed code, there's typically very little reason to do this.  If you want that level of control, you might consider using unmanaged code instead.
    Coding Light - Illuminated Ideas and Algorithms in Software
    Coding Light WikiLinkedInForumsBrowser
    Thursday, September 3, 2009 3:38 PM
    Moderator
  • Here's some dangerously unsafe stuff ....

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Runtime.InteropServices;

    // WEB LINKS
    //
    // http://social.msdn.microsoft.com/Search/en-US/?query=object%20instance%20memory%20allocation%20in%20c%23&refinement=117&ac=3
    //
    // http://msdn.microsoft.com/en-us/library/aa664786.aspx
    // http://msdn.microsoft.com/en-US/library/8ky2wh64(VS.80).aspx
    // http://msdn.microsoft.com/en-us/magazine/cc163791.aspx
    // http://msdn.microsoft.com/en-us/library/ms173104.aspx
    //


    namespace UnSafeMemory
    {

        public unsafe class Memory
        {
            // Handle for the process heap. This handle is used in all calls to the
            // HeapXXX APIs in the methods below.
            static int ph = GetProcessHeap();
            // Private instance constructor to prevent instantiation.
            private Memory()
            {
            }
            // Allocates a memory block of the given size. The allocated memory is
            // automatically initialized to zero.
            public static void* Alloc(int size)
            {
                void* result = HeapAlloc(ph, HEAP_ZERO_MEMORY, size);
                if (result == null)
                    throw new OutOfMemoryException();
                return result;
            }
            // Copies count bytes from src to dst. The source and destination
            // blocks are permitted to overlap.
            public static void Copy(void* src, void* dst, int count)
            {
                byte* ps = (byte*)src;
                byte* pd = (byte*)dst;
                if (ps > pd)
                {
                    for (; count != 0; count--)
                        *pd++ = *ps++;
                }
                else if (ps < pd)
                {
                    for (ps += count, pd += count; count != 0; count--)
                        *--pd = *--ps;
                }
            }
            // Frees a memory block.
            public static void Free(void* block)
            {
                if (!HeapFree(ph, 0, block))
                    throw new InvalidOperationException();
            }
            // Re-allocates a memory block. If the reallocation request is for a
            // larger size, the additional region of memory is automatically
            // initialized to zero.
            public static void* ReAlloc(void* block, int size)
            {
                void* result = HeapReAlloc(ph, HEAP_ZERO_MEMORY, block, size);
                if (result == null)
                    throw new OutOfMemoryException();
                return result;
            }
            // Returns the size of a memory block.
            public static int SizeOf(void* block)
            {
                int result = HeapSize(ph, 0, block);
                if (result == -1)
                    throw new InvalidOperationException();
                return result;
            }
            // Heap API flags
            const int HEAP_ZERO_MEMORY = 0x00000008;
            // Heap API functions
            [DllImport("kernel32")]
            static extern int GetProcessHeap();
            [DllImport("kernel32")]
            static extern void* HeapAlloc(int hHeap, int flags, int size);
            [DllImport("kernel32")]
            static extern bool HeapFree(int hHeap, int flags, void* block);
            [DllImport("kernel32")]
            static extern void* HeapReAlloc(int hHeap, int flags,
               void* block, int size);
            [DllImport("kernel32")]
            static extern int HeapSize(int hHeap, int flags, void* block);
        }
    }


    Rudedog   =8^D

    Mark the best replies as answers. "Fooling computers since 1971."
    Thursday, September 3, 2009 3:38 PM
    Moderator
  • Yes, the stack trace can give you different results between build types - but, I would sort of expect that, compiler optimizations and all :)
    Tom Shelton
    Thursday, September 3, 2009 3:55 PM
  • Rude,

    GetProcessHeap gives you the native process's heap - and while the CLI heap may indeed be contained within it (but not necessarily so I'd think), that's not what the OP's looking for. Seems to me the OP wants to examine the GC heap, possibly as an educational experiment.
    http://blog.voidnish.com
    Thursday, September 3, 2009 4:14 PM
    Moderator
  • You can use the microsoft debuggers like windbg or cdb to analyse the heap and stack of a .net application along with .net performance counters. In order to look at the managed structures in windbg or cdb you have to load the SOS dll which is part of the Framework. Using commands like "!dumpheap -stat" or "!dumpstack" you can look at the objects in the heap or stack. You can set break points and also look at the effect of different operations in your code. The allocated size can of all the GC heaps (gen0, 1, 2 and the large object heap)  can be monitored using the .net performance counters installed by default with the framework.
    Thursday, September 3, 2009 4:26 PM