Professional Windows hosting from ORCS Web
    
An Unrivaled Windows Hosting Experience    
1-888-313-9421  |  webteam@orcsweb.com        
From Our Clients:
"Wow! Talk about on the ball. ORCS never ceases to amaze me with their support. I wish my other provider would take a lesson from ORCS. I'd sleep better at night!"

Join our community of clients at: 1-888-313-9421

Get Memory Size Usage Using WMI and .NET 2.0.
By Steve Schofield
April 26, 2006

This article shows how to retrieve Physical and Virtual memory usage on a specific process using WMI (Windows Management Instrumentation). WMI is Microsoft's implementation of WBEM (Web-Based Enterprise Management). Click here for more information on WBEM.

Most administrators are familiar with viewing information in task manager. One of the most common things I look for are memory settings.

Note: the example below shows the physical memory usage for the 'sqlserver.exe' process at 43,716 K and Virtual memory size of 55,376 K. This is a 'moment in time' setting and can change often.

 

Using this code sample can help query a remote machine on a periodic basis to identify offending processes. I use this technique to monitor 'W3WP.exe' processes on shared web servers to identify high memory application pools.

The code sample returns all the information in the Win32_Process class regarding just the 'W3WP.exe' process. You could do this for other processes too. The one additional function also returns the 'owner' of the thread, which I found required an additional step to query with the 'thread handle'. 

The other feature in the component is the ability to pass custom user id and password to the remote machine. This can be handy to not assume the user id credentials the process is running under.

Imports System.Management

Imports System.Data.SqlClient

 

Module Module1

    Private _ComputerName As String = "."

    Private _UserName As String = "Changeme to Run on a remote machine"

    Private _Password As String = "Changeme to Run on a remote machine"

    Private _SelectQuery As String = "SELECT * FROM Win32_Process WHERE name='w3wp.exe'"

    Private _DateEntered As DateTime = System.DateTime.Now()

 

    Sub Main()

        Try

            GetProcessInfo()

        Catch f As Exception

            ErrorHandler(f)

        End Try

    End Sub

 

    Sub GetProcessInfo()

        Try

            '**********************************************

            'Uncomment this out if you want to run on a remote machine and

            'comment out the other 'scope' variable

            'You will get an error about trying pass credentials to the local machine

            '

            'Dim options As New ConnectionOptions()

            'options.Username = _UserName

            'options.Password = _Password

 

            'Dim scope As New ManagementScope("\\" & _ComputerName & "\root\cimv2", options)

            '**********************************************

 

            'Comment this out if you are going to test on a remote machine

            'This will default to authenticating to the local machine

            Dim scope As New ManagementScope("\\" & _ComputerName & "\root\cimv2")

 

            Dim selectQuery As New SelectQuery(_SelectQuery)

            Dim searcher As New ManagementObjectSearcher(scope, selectQuery)

 

            Try

                scope.Connect()

            Catch f As Exception

                ErrorHandler(f)

                Exit Sub

            End Try

 

 

            For Each queryObj As ManagementObject In searcher.Get()

                Console.WriteLine(queryObj("WorkingSetSize") / 1024)

                Console.WriteLine(queryObj("PeakWorkingSetSize") / 1024)

                Console.WriteLine(queryObj("PageFileUsage") / 1024)

                Console.WriteLine(queryObj("PeakPageFileSystem") / 1024)

                Console.WriteLine(GetOwnerObject(queryObj("Handle")))

            Next

        Catch f As Exception

            ErrorHandler(f)

        End Try

    End Sub

 

    Function GetOwnerObject(ByVal strHandle As String) As Object

        Dim options As New ConnectionOptions()

        options.Username = _UserName

        options.Password = _Password

 

        '**********************************************

        'Uncomment this out if you want to run on a remote machine and

        'comment out the other 'scope' variable

        'You will get an error about trying pass credentials to the local machine

        '

        'Dim options As New ConnectionOptions()

        'options.Username = _UserName

        'options.Password = _Password

        'Dim s As New ManagementScope("\\" & _ComputerName & "\root\cimv2", options)

        '**********************************************

 

        'Comment this out if you are going to test on a remote machine

        'This will default to authenticating to the local machine

        Dim s As New ManagementScope("\\" & _ComputerName & "\root\cimv2", options)

 

        Dim p As New ManagementPath( _

            "Win32_Process.Handle='" & strHandle & "'")

 

        Dim opt As ObjectGetOptions

        opt = New ObjectGetOptions()

 

        Dim o As ManagementObject

        o = New ManagementObject(s, p, opt)

 

        ' Execute the method and obtain the return values.

        Dim outParams As ManagementBaseObject = _

            o.InvokeMethod("GetOwner", Nothing, Nothing)

        Return outParams("User").ToString()

    End Function

 

    Sub ErrorHandler(ByVal exp As Exception)

        Dim LogName As String

        Dim Message As String

        Dim Log As New System.Diagnostics.EventLog

 

        Try

            LogName = "Application"

            Message = "Message: " & exp.ToString()

 

            If (Not System.Diagnostics.EventLog.SourceExists(LogName)) Then

                System.Diagnostics.EventLog.CreateEventSource(LogName, LogName)

            End If

 

            Log.Source = LogName

            Log.WriteEntry(Message)

            Log.Close()

            Log.Dispose()

        Catch ex As Exception

        End Try

    End Sub

 

End Module


Conclusion

In conclusion, this code snippet can help an IIS administrator manage their web servers and monitor 'W3WP.exe' resource usage. This information could be recorded to a database and used for future reporting purposes.
Steve Schofield is a Senior Internet Support Specialist with ORCS Web, Inc. - a company that provides managed hosting solutions for clients who develop and deploy their applications on Microsoft Windows platforms. Services include shared hosting, dedicated hosting, and webfarm hosting, with specialty in .Net, SQL Server, and architecting highly scalable solutions.

Copyright © 1996-2010 ORCS Web, Inc. All rights reserved.