Monitoring Application Performance on the .NET Compact Framework Part II - Version 1 performance counters
In the first post of this series, I talked about how to enable collection of performance counter data in the .NET Compact Framework. In this installment, I'd like to talk a bit about the data collected by version 1 of the .NET Compact Framework.
The table below lists the performance data collected by version 1 of the .NET Compact Framework. For convenience of discussing the counters, I have grouped them by category (Garbage Collector, etc).
Execution Engine | |
Execution Engine Startup Time | |
Total Program Run Time | |
Garbage Collector | |
Peak Bytes Allocated | |
Number Of Objects Allocated | |
Bytes Allocated | |
Number Of Simple Collections | |
Bytes Collected By Simple Collection | |
Bytes In Use After Simple Collection | |
Time In Simple Collect | |
Number Of Compact Collections | |
Bytes Collected By Compact Collection | |
Bytes In Use After Compact Collection | |
Time In Compact Collection | |
Number Of Full Collections | |
Bytes Collected By Full Collection | |
Bytes In Use After Full Collection | |
Time In Full Collection | |
Number Of Application Induced Collections | |
Total Bytes In Use After Collection | |
IL | |
Bytes Jitted | |
Native Bytes Jitted | |
Number Of Methods Jitted | |
Bytes Pitched | |
Number Of Methods Pitched | |
Number Of Exceptions | |
Number Of Calls | |
Number Of Virtual Calls | |
Number Of Virtual Call Cache Hits | |
Number Of PInvoke Calls |
The mscoree.stat
file includes running totals, count (n), average (mean), minimum and maximum values for the above mentioned counters. I've included an example file below. For counters where count, mean, minimum and maximum data is not relevant (ex: Total Program Run Time) a value of zero (0) is logged.
The sections below discuss each counter in the mscoree.stat
file. I will use the following format for the discussions.
Counter name
Brief description of the counter
Discussion of the contents of relevant columns (value, n. mean, min, max)
Any additional comments relating to the counter
Execution Engine Counters
In version 1 of the .NET Compact Framework, there are two Execution Engine counters: Execution Engine Startup Time and Total Program Run Time.
Execution Engine Startup Time
Time to get to your application's entry point (Main).
value: Time in milliseconds
This counter is not of use to application writers and has been removed from version 2 of the .NET Compact Framework.
Total Program Run Time
Total application run time, including Execution Engine startup.
value: Time in milliseconds
Garbage Collector Counters
Many of the Garbage Collector counters are related to a collection type (simple, compact, full). For information on the .NET Compact Framework Garbage Collector, please see Steven Pratschner's post: An Overview of the .NET Compact Framework Garbage Collector. In the discussion below, substitute <type> with Simple, Compact or Full depending on which counters you are examining.
Number Of <type> Collections
This counter reports the number of garbage collections (of the specified type) that occurred during your application's run time.
value: Garbage collection count
Bytes Collected By <type> Collection
The total number of bytes that were collected by the collections that occurred while your application ran.
value: Running total of bytes collected
n: The number of collections
mean: The average number of bytes collected during each collection
min: The smallest amount of bytes collected
max: The largest amount of bytes collected
Bytes In Use After <type> Collection
The total number of bytes in use, by managed objects, in your application, after garbage collection of the specified type occurs
value: Running total of bytes available after collection
n: The number of collections
mean: The average number of bytes in use after collection
min: The smallest amount of bytes in use after collection
max: The largest amount of bytes in use after collection
The value column is an accumulation of total bytes after collection, it is not of much use when diagnosing performance issues. This total is combined with the count of collections (n column) to compute the mean. For this counter, the mean, min and max columns provide the useful data.
Time In <type> Collect
The time spent in all collections of the specified type.
value: Running total of the time (in milliseconds) spent in collections
n: The number of collections
mean: The average length of time to perform the collection
min: The shortest length of time spent in collection
max: The longest length of time spent in collection
The following counters are related to the Garbage Collector as a whole, and not a specific collection type.
GC Number Of Application Induced Collections
The number of garbage collections that occurred as a result of the application calling GC.Collect().
value: The number of collections
For a detailed discussion of the issues surrounding GC.Collect(), please see Scott Holden's post: The perils of GC.Collect.
GC Latency Time
The time spent in all collections of all types.
value: Running total of the time (in milliseconds) spent in collections
n: The number of collections
mean: The average length of time to perform the collection
min: The shortest length of time spent in collection
max: The longest length of time spent in collection
Total Bytes In Use After Collection
The total number of bytes in use, by managed objects, in your application, after garbage collection of any type occurs
value: Running total of bytes available after collection
n: Number of garbage collections
mean: The average number of bytes in use after collection
min: The smallest amount of bytes in use after collection
max: The largest amount of bytes in use after collection
The value column is an accumulation of total bytes after collection, it is not of much use when diagnosing performance issues. This total is combined with the count of collections (n column) to compute the mean. For this counter, the mean, min and max columns provide the useful data.
Bytes Allocated
The amount of memory allocated for managed objects, Just-In-Time compiled code and runtime data structures during the run time of your application.
value: Running total of bytes allocated
n: Number of allocations
mean: Average allocation size
min: Size of smallest allocation
max: Size of largest allocation
Please note that memory allocated by P/Invoke calls is not tracked as a part of this counter.
Peak Bytes Allocated
The maximum amount of memory allocated for managed objects, Just-In-Time compiled code and runtime data structures, at any time during the run time of your application.
value: The largest number of bytes used by the application
I find this to be one of the most useful performance counters. By tracking peak memory usage across multiple application runs (where the same scenario is performed), memory consumption related issues can be identified at a high level.
Please note that memory allocated by P/Invoke calls is not tracked as a part of this counter.
Number Of Objects Allocated
The number of managed objects allocated by your application.
value: Running total of allocated objectsThis counter includes object that have been disposed / collected.
IL Counters
The counters in this section are related to the .NET Compact Framework's Just-In-Time (JIT) compiler.
Bytes Jitted
The pre-compile size of the IL code being Just-In-Time compiled.
value: Running total of bytes compiled
n: Number of compilations
mean: Average number of bytes in each compilation
min: Smallest number of bytes compiled
max: Largest number of bytes compiled
Native Bytes Jitted
The post-compile size of the IL code being Just-In-Time compiled.
value: Running total of bytes compiled
n: Number of compilations
mean: Average number of bytes in each compilation
min: Smallest number of bytes compiled
max: Largest number of bytes compiled
Number Of Methods Jitted
A count of methods which have been Just-In-Time compiled.
value: Running total of compiled methods
Bytes Pitched
Number of bytes removed from the code cache.
value: Running total of removed bytes
n: Number of times code was removed from the cache
mean: Average size of the removed code
min: Size of smallest code removal
max: Size of largest code removal
This counter will show non-zero data only if the application has encountered extreme memory pressure.
Number Of Methods Pitched
Number of jitted methods removed from the code cache.
value: Running total of removed methods
n: Number of times code was removed from the cache
This counter will show non-zero data only if the application has encountered extreme memory pressure.
Number Of Exceptions
Number of managed exceptions thrown while the application was running.
value: Running total of thrown exceptions
Number Of Calls
Number of direct calls to managed methods.
value: Running total of method calls
It is important to note that the calls collected in this counter do not include calls to virtual methods. Virtual method calls are collected in the Number Of Virtual Calls counter.
Number Of Virtual Calls
Number of virtual calls to managed methods.
value: Running total of method calls
Number Of Virtual Call Cache Hits
Number of virtual calls to methods which have been cached.
value: Running total of virtual method calls from the cache
The value in this counter will often be very close to the value of the Number Of Virtual Calls counter. Where these counter values differ is in the initial call (including re-calls after a method is pitched).
The Number Of PInvoke Calls
The number of calls into native functions made (via P/Invoke) by your application.
value: Running total of native function calls
Example mscoree.stat file
The following is an example mscoree.stat file that shows the data collected from a simple application. The garbage collections in this application were caused by moving it to the background (running a second application in the foreground).
counter | value | n | mean | min | max |
Execution Engine Startup Time | 11278 | 0 | 0 | 0 | 0 |
Total Program Run Time | 333223 | 0 | 0 | 0 | 0 |
Peak Bytes Allocated | 214563 | 0 | 0 | 0 | 0 |
Number Of Objects Allocated | 2928 | 0 | 0 | 0 | 0 |
Bytes Allocated | 116256 | 2928 | 39 | 8 | 1296 |
Number Of Simple Collections | 0 | 0 | 0 | 0 | 0 |
Bytes Collected By Simple Collection | 0 | 0 | 0 | 0 | 0 |
Bytes In Use After Simple Collection | 0 | 0 | 0 | 0 | 0 |
Time In Simple Collect | 0 | 0 | 0 | 0 | 0 |
Number Of Compact Collections | 0 | 0 | 0 | 0 | 0 |
Bytes Collected By Compact Collections | 0 | 0 | 0 | 0 | 0 |
Bytes In Use After Compact Collection | 0 | 0 | 0 | 0 | 0 |
Time In Compact Collect | 0 | 0 | 0 | 0 | 0 |
Number Of Full Collections | 3 | 0 | 0 | 0 | 0 |
Bytes Collected By Full Collection | 62800 | 3 | 20933 | 14504 | 25800 |
Bytes In Use After Full Collection | 139876 | 3 | 46625 | 41068 | 49640 |
Time In Full Collection | 106 | 3 | 35 | 31 | 38 |
GC Number Of Application Induced Collections | 0 | 0 | 0 | 0 | 0 |
GC Latency Time | 106 | 3 | 35 | 31 | 38 |
Bytes Jitted | 24699 | 414 | 59 | 1 | 2109 |
Native Bytes Jitted | 78900 | 414 | 190 | 24 | 4708 |
Number of Methods Jitted | 414 | 0 | 0 | 0 | 0 |
Bytes Pitched | 0 | 0 | 0 | 0 | 0 |
Number of Methods Pitched | 0 | 0 | 0 | 0 | 0 |
Number of Exceptions | 0 | 0 | 0 | 0 | 0 |
Number of Calls | 12198 | 0 | 0 | 0 | 0 |
Number of Virtual Calls | 4084 | 0 | 0 | 0 | 0 |
Number of Virtual Call Cache Hits | 3996 | 0 | 0 | 0 | 0 |
Number of PInvoke Calls | 969 | 0 | 0 | 0 | 0 |
Total Bytes In Use After Collection | 541953 | 3 | 180651 | 179219 | 181787 |
Recommended reading
For anyone building applications on the .NET Compact Framework, I highly recommend the reading the following:
.NET Compact Framework version 2.0 Performance and Working Set FAQ - by Roman Batoukov
This article (on the .NET Compact Framework Team weblog) is very thorough and covers many performance issues and how to avoid them. While the article specifically talks about version 2 of the .NET Compact Framework, many of its recommendations apply to version 1 as well.
When Performance Matters and The Perils of GC.Collect (or when to use GC.Collect) - by Scott Holden
.NET Compact Framework Advanced Memory Management - by Mike Zintel
An Overview of the .NET Compact Framework Garbage Collector - by Steven Pratschner
I'll be posting on the .NET Compact Framework version 2 performance counters soon. Given the length of this post, and the larger number of counters in version 2, I will likely split the discussion into multiple (smaller) posts around counter categories.
Take care,
-- DK
[Edit: post title]
Disclaimer(s):
This posting is provided "AS IS" with no warranties, and confers no rights.