Use Perfmon to analyze your managed memory

You can learn all sorts of information about your application using Perfmon. You can also inspect various aspects of managed memory.

 

How much time is spent in garbage collection? When managed code runs, memory management is done for you, but at the cost of freezing your application while GC is doing its thing.

 

The sample code below creates many instances of a class called Big, which can hold a reference to another of the same class. If the instances of Big are linked together, they can’t be GC’d, til the end of the loop so the memory footprint is very different without the links.

 

Start VS 2010, File->New->Project->C#->Windows->WpfApplication,

Open the MainWindow.xaml.cs file, replace with the code below

Hit F5 to run.

 

Start Perfmon: Windows Key+R Perfmon

Click on Performance Monitor in tree on left.

By default, % Processor time is displayed in a graph

Click the big red X to delete it.

Click the big green + to bring up the Add Counters dialog to add some things to monitor

 

Click on “.NET CLR Memory” in the first listbox.

 

For Instances of selected object:, choose “WpfApplciation1.vshost” and then click “Add”, “OK”

 

These are the performance counters graphed on Windows 7:

# Bytes in all Heaps

# GC Handles

# Gen 0 Collections

# Gen 1 Collections

# Gen 2 Collections

# Induced GC

# of Pinned Objects

# of Sink Blocks in use

# Total committed Bytes

# Total reserved Bytes

% Time in GC

Allocated Bytes/sec

Finalization Survivors

Gen 0 heap size

Gen 0 Promoted Bytes/Sec

Gen 1 heap size

Gen 1 Promoted Bytes/Sec

Gen 2 heap size

Large Object Heap size

Process ID

Promoted Finalization-Memory from Gen 0

Promoted Memory from Gen 0

Promoted Memory from Gen 1

 

 

You can select various ones individually by clicking on the associated Show checkbox.

Try looking at these closely:

Gen 0 heap size

Gen 1 heap size

Gen 2 heap size

% Time in GC

 

MultiSelect a few and right click ->Scale selected counters if you like.

 

At one point (change the size of the Big array to 10000), I got 70% time in garbage collection! (The values in the Textboxes are not scaled, and it showed 47.)

 

Try commenting out the backlink line (ptrPrev assignment) or vary the size of Big and see the effect.

 

 

 

See also

Examine .Net Memory Leaks

Heartbeat: Garbage collection in VFP and .NET are similar

Use temporary projects in Visual Studio

PerfMon Sample: Demonstrates How to Monitor System Performance Using Performance Counters

Managed code using unmanaged memory: HeapCreate, Peek and Poke

 

<C# Code>

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Windows;

using System.Windows.Controls;

using System.Windows.Data;

using System.Windows.Documents;

using System.Windows.Input;

using System.Windows.Media;

using System.Windows.Media.Imaging;

using System.Windows.Navigation;

using System.Windows.Shapes;

namespace WpfApplication1

{

    /// <summary>

    /// Interaction logic for MainWindow.xaml

    /// </summary>

    public partial class MainWindow : Window

    {

        public MainWindow()

        {

            InitializeComponent();

            for (int i = 0; i < 1000; i++)

            {

                System.Diagnostics.Debug.WriteLine(i.ToString());

                var root = new Big();

                var ptrCurrent = root;

                for (int j = 0; j < 30000; j++)

                {

                    var big = new Big();

                    big.ptrPrev = ptrCurrent; // make them all link together so they can't be collected

                    ptrCurrent = big;

                    System.Threading.Thread.Sleep(1);

                }

            }

        }

        public class Big

        {

            public int[] data;

            public Big ptrPrev; // backlink

            public Big()

            {

                data = new int[1000];

            }

        }

    }

}

 </C# Code>

 

<VB Code>

Class MainWindow

    Private Sub Window_Loaded(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles MyBase.Loaded

        For i = 0 To 1000

            System.Diagnostics.Debug.WriteLine(i.ToString())

            Dim root = New Big()

            Dim ptrCurrent = root

            For j = 0 To 30000

                Dim big = New Big()

                big.ptrPrev = ptrCurrent ' make them all link together so they can't be collected

                ptrCurrent = big

                System.Threading.Thread.Sleep(1)

            Next

        Next

    End Sub

    Class Big

        Dim data(1000) As Integer

        Public ptrPrev As Big

    End Class

End Class

</VB Code>

 

 

 

Thanks, Calvin

https://blogs.msdn.com/calvin_hsia