ENTERPRISE

Memory Management : Get the OS View of Your Application's Memory, Clean Up Unmanaged Resources Using Finalization

9/22/2012 9:17:15 PM

Measure Memory Usage of Your Application

Scenario/Problem:You need to find out how much memory your application is using.
Solution:The GC class contains many handy memory-related methods, including GetTotalMemory(), which is the amount of memory the garbage collector thinks is allocated to your application. The number may not be exactly right because of objects that haven’t been garbage collected yet. However, this has the advantage of being able to tell you about how much memory a certain part of your program uses, rather than the entire process.
long available = GC.GetTotalMemory(false);
Console.WriteLine("Before allocations: {0:N0}", available);

int allocSize = 40000000;
byte[] bigArray = new byte[allocSize];

available = GC.GetTotalMemory(false);
Console.WriteLine("After allocations: {0:N0}", available);

This same code prints the following:

Before allocations: 651,064
After allocations: 40,690,080

Get the OS View of Your Application’s Memory

You can also ask the operating system to give you information about your process:

//the Process class is in the System.Diagnostics namespace
Process proc = Process.GetCurrentProcess();
Console.WriteLine("Process Info: "+Environment.NewLine+
    "Private Memory Size: {0:N0}"+Environment.NewLine +
    "Virtual Memory Size: {1:N0}" + Environment.NewLine +
    "Working Set Size: {2:N0}" + Environment.NewLine +
    "Paged Memory Size: {3:N0}" + Environment.NewLine +
    "Paged System Memory Size: {4:N0}" + Environment.NewLine +
    "Non-paged System Memory Size: {5:N0}" + Environment.NewLine,
    proc.PrivateMemorySize64,
    proc.VirtualMemorySize64,
    proc.WorkingSet64,
    proc.PagedMemorySize64,
    proc.PagedSystemMemorySize64,
    proc.NonpagedSystemMemorySize64 );

Here’s the output:

Process Info:
Private Memory Size: 75,935,744
Virtual Memory Size: 590,348,288
Working Set Size: 29,364,224
Paged Memory Size: 75,935,744
Paged System Memory Size: 317,152
Non-paged System Memory Size: 37,388

What each of those numbers mean is not necessarily intuitive, and you should consult a good operating system book, such as Windows Internals (Microsoft Press), to learn more about how virtual memory works.

Note

You can also use performance counters to track this and a lot of other information about your application or its environment. You can access these interactively from perfmon.exe, or see the MSDN documentation for the PerformanceCounter class to see how you can incorporate these into your own applications.

Clean Up Unmanaged Resources Using Finalization

Scenario/Problem:You have a native resource (such as a kernel object) and need to ensure that it gets cleaned up by the garbage collector.

If for some reason you want to manage raw file handles, bitmaps, memory-mapped files, synchronization objects, or any other kernel object, you need to ensure that the resource is cleaned up. Each of these resources is represented by handles. To manipulate handles, you need to use native Windows functions via P/Invoke 

Solution:Here’s an example of a class that manages a file handle with help from the .NET classes:
using System;
using System.IO;
using System.Runtime.InteropServices;

namespace Finalizer
{
    public class MyWrappedResource
    {
        [DllImport("kernel32.dll", CharSet = CharSet.Auto,
            CallingConvention = CallingConvention.StdCall,
            SetLastError = true)]
        public static extern IntPtr CreateFile(
              string lpFileName,
              uint dwDesiredAccess,
              uint dwShareMode,
              IntPtr SecurityAttributes,
              uint dwCreationDisposition,
              uint dwFlagsAndAttributes,
              IntPtr hTemplateFile
              );

        [DllImport("kernel32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool CloseHandle(IntPtr hObject);

        //IntPtr is used to represent OS handles
        IntPtr _handle = IntPtr.Zero;

        public MyWrappedResource(string filename)
        {
            _handle = CreateFile(filename,
                0x80000000, //access read-only
                1,          //share-read
                IntPtr.Zero,
                3,          //open existing
                0,
                IntPtr.Zero);
        }

        //Finalizers look like C++ destructors,
        //but they are NOT deterministic
        ~MyWrappedResource()
        {
            //note: in real apps, don't put anything
            //in finalizers that doesn't need to be there
            Console.WriteLine("In Finalizer");
            if (_handle != IntPtr.Zero)
            {
                CloseHandle(_handle);
            }
        }

        public void Close()
        {
            if (_handle != IntPtr.Zero)
            {
                //we're already closed, so this object
                //doesn't need to be finalized anymore
                GC.SuppressFinalize(this);
                CloseHandle(_handle);
            }
        }
    }
}

					  

When .NET detects a finalizer in a class, it ensures that it is called at some point in garbage collection.

Note

The finalization phase of the collection process can be quite expensive, so it’s important to use finalizers only when necessary. They should almost never be used for managed resources—only unmanaged ones.

Other  
  •  Active Directory Domain Services 2008 : Create a WMI Filter, Import a WMI Filter, Export a WMI Filter
  •  Active Directory Domain Services 2008 : Filter Group Policy Object Scope by Using Security Groups, Disable User Settings in a Group Policy Object, Disable Computer Settings in a Group Policy Object
  •  Active Directory Domain Services 2008 : Block & Remove Block Inheritance of Group Policy Objects, Change the Order of Group Policy Object Links
  •  The Future Of Apple: Chip Off The Block (Part 10)
  •  The Future Of Apple: Chip Off The Block (Part 9)
  •  The Future Of Apple: Chip Off The Block (Part 8)
  •  The Future Of Apple: Chip Off The Block (Part 7)
  •  The Future Of Apple: Chip Off The Block (Part 6)
  •  The Future Of Apple: Chip Off The Block (Part 5)
  •  The Future Of Apple: Chip Off The Block (Part 4)
  •  
    Most View
    Sharepoint 2010 : Administering Enterprise Content Management - Document Management (part 2) - Versioning , Information Management Policy
    Humax DTR-T1010 - Digital TV Recorders
    Windows Server 2003 : Using AD to Support Network Administration - Using Group Policy to Manage Network Protocols
    Roll Your Own Home Server (Part 1)
    Automation For The People
    Active Directory Domain Services 2008 : Delegate Permissions for Generating Group Policy Results
    Blackberry Z10 - It’s Up Against Some Tough Competition
    Sony VAIO Fit 13A Fit To Flip, Flip To Fit (Part 2)
    The Truth About Facebook Graph Search (Part 1)
    Windows Phone 8 In-Depth Review (Part 3)
    Top 10
    Mitsubishi Hybrids – One Direction
    Race To The Clouds – Honda R&D’S ’91 NSX (Part 2)
    Race To The Clouds – Honda R&D’S ’91 NSX (Part 1)
    Volkswagen Plug-In Hybrid Up – Double Act
    Pre/Power Amplifier Marantz SA8005/PM8005 Review (Part 2)
    Pre/Power Amplifier Marantz SA8005/PM8005 Review (Part 1)
    Smart TV Finlux 50FME242B-T Review (Part 2)
    Smart TV Finlux 50FME242B-T Review (Part 1)
    The Best Money Can Buy: Motherboards (Part 2) - Asus Rampage IV Black Edition, Asus Crosshair V Formula-Z
    The Best Money Can Buy: Motherboards (Part 1) - ASRock X79 Extreme 11, Asus Intel Z97 ROG Bundle, Gigabyte Z97X-GAMING G1