Monitoring Application Performance on the .NET Compact Framework Part IV - Version 2 performance counters (Part II: Generics counters)
In the previous installment, I discussed the .NET Compact Framework performance counters related to the loader. Today, I'd like to talk about the counters related to the new Generic feature of the .NET Compact Framework version 2.
This is the second part of the series describing .NET Compact Framwork v2 performance counters. A complete listing of this series, to date, is included below.
Pre-requisite:
Monitoring Application Performance on the .NET Compact Framework Part I - Enabling performance counters
.NET Compact Framework Version 1:
Monitoring Application Performance on the .NET Compact Framework Part II - Version 1 performance counters
.NET Compact Framework Version 2:
Monitoring Application Performance on the .NET Compact Framework Part III - Version 2 performance counters (Part I: Loader counters)
In each new installment, I will add to this list, to make referring back easier. I have also listed the earlier posts of the parent series on monitoring application performance.
The following table lists all of the performance counters available in version 2 of the .NET Compact Framework. The counters highlighted, in yellow, are the ones I will be talking about today.
Loader | |
Total Program Run Time (ms) | |
App Domains Created | |
App Domains Unloaded | |
Assemblies Loaded | |
Classes Loaded | |
Methods Loaded | |
Generics | |
Closed Types Loaded | |
Closed Types Loaded per Definition | |
Open Types Loaded | |
Closed Methods Loaded | |
Closed Methods Loaded per Definition | |
Open Methods Loaded | |
Locks and Threads | |
Threads in Thread Pool | |
Pending Timers | |
Scheduled Timers | |
Timers Delayed by Thread Pool Limit | |
Work Items Queued | |
Uncontested Monitor.Enter Calls | |
Contested Monitor.Enter Calls | |
Garbage Collector | |
Peak Bytes Allocated (native + managed) | |
Managed Objects Allocated | |
Managed Bytes Allocated | |
Managed String Objects Allocated | |
Bytes of String Objects Allocated | |
Garbage Collections (GC) | |
Bytes Collected By GC | |
Managed Bytes In Use After GC | |
Total Bytes In Use After GC | |
GC Compactions | |
Code Pitchings | |
Calls to GC.Collect | |
GC Latency Time (ms) | |
Pinned Objects | |
Objects Moved by Compactor | |
Objects Not Moved by Compactor | |
Objects Finalized | |
Boxed Value Types | |
Process Heap | |
Short Term Heap | |
JIT Heap | |
App Domain Heap | |
GC Heap | |
JIT Compiler | |
Native Bytes Jitted | |
Methods Jitted | |
Bytes Pitched | |
Methods Pitched | |
Method Pitch Latency Time (ms) | |
Exceptions | |
Exceptions Thrown | |
Interop | |
Platform Invoke Calls | |
COM Calls Using a vtable | |
COM Calls Using IDispatch | |
Complex Marshaling | |
Runtime Callable Wrappers | |
Networking | |
Socket Bytes Sent | |
Socket Bytes Received | |
Windows.Forms | |
Controls Created | |
Brushes Created | |
Pens Created | |
Bitmaps Created | |
Regions Created | |
Fonts Created | |
Graphics Created (FromImage) | |
Graphics Created (CreateGraphics) |
The statistics file includes running totals, the most recent value (last datum), count (n), average (mean), minimum and maximum values for the counters. I've included an example file at the end of this post. For counters where a given column is not relevant, a hyphen (-) is logged.
I will use the following format to describe each counter.
Counter name
Brief description of the counter
Discussion of the contents of relevant columns (total, last datum, n, mean, min, max)
Any additional comments relating to the counter
Generics Counters
The generics counters are loader counters that are specific to the generics feature of the .NET Compact Framework version 2. Since the runtime internally uses generics, you may see values in these counters even if your application does not use generics explicitly. For an excellent discussion of generics and the .NET Compact Framework, please see Generics in the .NET Compact Framework by Roman Batoukov.
Closed Types Loaded
The count of unique generic types that have been created across all App Domains.
total: Running total of created generic types
A closed type is a generic class that has been bound with a specific data type. For example, an instance of MyGenericType<Int32>
is a closed type.
Closed Types Loaded per Definition
The maximum number of unique generic types created for a given definition across all App Domains.
total: Running total of created generic types (will match the total in the Closed Types Loaded counter)
last datum: The number of unique generic types created for the most recent definition
n: The number of generic type definitions
mean: The average number of unique generic types created for a definition
min: The smallest number of unique generic types created for a definition
max: The largest number of unique generic types created for a definition
For example, if an application instantiates MyGenericType<Int32>
, MyGenericType<String>
and MyGenericType<Single>
, the number of closed types loaded for the MyGenericType<T>
definition is three (3).
When looking at the Closed Types Loaded per Definition counter, the most interesting value is in the max column. If this number is large (on the order of several hundred), this can indicate working set pressure in terms of JIT compiled code and Execution Engine data structures.
Open Types Loaded
The count of open generic types create across all App Domains.
total: Running total of generic types created which have not been bound
Open types are typically created in Reflection scenarios. An open type is a generic type that has been loaded, but not bound to a specific type. For example, loading an instance of MyGenericType<T>
via reflection will increment the Open Types Loaded counter, once the type has been bound (ex: MyGenericType<String>
) it becomes a closed type and the Closed Types Loaded counter is incremented. It is good to note that the .NET Compact Framework runtime at times (ex: XmlSerialization, Web Services) will use reflection internally and can be the source of the open types.
Closed Methods Loaded
The count of unique generic methods that have been loaded across all App Domains.
total: Running total of created generic methods
A closed method is a generic method that has been bound with a specific data type. The type containing the method may or may not be a generic type. For example, an instance of MyType.ProcessData<Int32>()
is a closed method.
Closed Methods Loaded per Definition
The maximum number of unique generic methods created for a given definition across all App Domains.
total: Running total of created generic methods (will match the total in the Closed Methods Loaded counter)
last datum: The number of unique generic methods created for the most recent definition
n: The number of generic method definitions
mean: The average number of unique generic methods created for a definition
min: The smallest number of unique generic methods created for a definition
max: The largest number of unique generic methods created for a definition
The Closed Methods Loaded per Definition counter is very similar to Closed Types Loaded per Definition. Using the following instances of MyType.ProcessData<Int32>()
, MyType.ProcessData<String>()
and MyType.ProcessData<Single>()
will create three (3) closed methods for the MyType.ProcessData<T>()
definition.
As with the Closed Types Loaded per Definition counter, in large (on the order of several hundred) max value scenarios, this can indicate working set pressure in terms of JIT compiled code and Execution Engine data structures.
Open Methods Loaded
The count of open generic methods created across all App Domains.
total: Running total of generic methods created which have not been bound
Open methods are typically created in Reflection scenarios. An open type is a generic method that has been loaded, but not bound to a specific type. For example, loading an instance of MyType.ProcessData<T>()
via reflection will increment the Open Types Loaded counter, once the method has been bound (ex: MyType.ProcessData<Int32>()
) it becomes a closed method and the Closed Methods Loaded counter is also incremented. It is good to note that the .NET Compact Framework runtime uses reflection internally and can be the source of the open methods.
Example statistics file
The following is the same example statistics file from last time, showing the data collected by running a simple application.
As with the counters table, I have highlighted the counters discussed here with a yellow background.
counter | total | last datum | n | mean | min | max |
Total Program Run Time (ms) | 2956837 | - | - | - | - | - |
App Domains Created | 1 | - | - | - | - | - |
App Domains Unloaded | 1 | - | - | - | - | - |
Assemblies Loaded | 8 | - | - | - | - | - |
Classes Loaded | 975 | - | - | - | - | - |
Methods Loaded | 3015 | - | - | - | - | - |
Closed Types Loaded | 75 | - | - | - | - | - |
Closed Types Loaded per Definition | 75 | 3 | 22 | 3 | 1 | 10 |
Open Types Loaded | 13 | - | - | - | - | - |
Closed Methods Loaded | 3 | - | - | - | - | - |
Closed Methods Loaded per Definition | 3 | 1 | 3 | 1 | 1 | 1 |
Open Methods Loaded | 0 | - | - | - | - | - |
Threads in Thread Pool | - | 0 | 2 | 0 | 0 | 1 |
Pending Timers | - | 0 | 4 | 0 | 0 | 1 |
Scheduled Timers | 2 | - | - | - | - | - |
Timers Delayed by Thread Pool Limit | 0 | - | - | - | - | - |
Work Items Queued | 2 | - | - | - | - | - |
Uncontested Monitor.Enter Calls | 664 | - | - | - | - | - |
Contested Monitor.Enter Calls | 0 | - | - | - | - | - |
Peak Bytes Allocated (native + managed) | 2789048 | - | - | - | - | - |
Managed Objects Allocated | 25883 | - | - | - | - | - |
Managed Bytes Allocated | 1366120 | 24 | 25883 | 52 | 8 | 135796 |
Managed String Objects Allocated | 5360 | - | - | - | - | - |
Bytes of String Objects Allocated | 124412 | - | - | - | - | - |
Garbage Collections (GC) | 1 | - | - | - | - | - |
Bytes Collected By GC | 897140 | 897140 | 1 | 897140 | 897140 | 897140 |
Managed Bytes In Use After GC | - | 147292 | 1 | 147292 | 147292 | 147292 |
Total Bytes In Use After GC | - | 2621848 | 1 | 2621848 | 2621848 | 2621848 |
GC Compactions | 0 | - | - | - | - | - |
Code Pitchings | 0 | - | - | - | - | - |
Calls to GC.Collect | 0 | - | - | - | - | - |
GC Latency Time (ms) | 46 | 46 | 1 | 46 | 46 | 46 |
Pinned Objects | 0 | - | - | - | - | - |
Objects Moved by Compactor | 0 | - | - | - | - | - |
Objects Not Moved by Compactor | 0 | - | - | - | - | - |
Objects Finalized | 82 | - | - | - | - | - |
Boxed Value Types | 3273 | - | - | - | - | - |
Process Heap | - | 1280 | 7484 | 198308 | 72 | 330016 |
Short Term Heap | - | 0 | 6382 | 963 | 0 | 42136 |
JIT Heap | - | 0 | 6402 | 421097 | 0 | 876976 |
App Domain Heap | - | 0 | 18679 | 324926 | 0 | 523240 |
GC Heap | - | 0 | 30 | 527974 | 0 | 1060864 |
Native Bytes Jitted | 844928 | 208 | 1963 | 430 | 84 | 9684 |
Methods Jitted | 1963 | - | - | - | - | - |
Bytes Pitched | 0 | 0 | 0 | 0 | 0 | 0 |
Methods Pitched | 0 | - | - | - | - | - |
Method Pitch Latency Time (ms) | 0 | 0 | 0 | 0 | 0 | 0 |
Exceptions Thrown | 4 | - | - | - | - | - |
Platform Invoke Calls | 0 | - | - | - | - | - |
COM Calls Using a vtable | 0 | - | - | - | - | - |
COM Calls Using IDispatch | 0 | - | - | - | - | - |
Complex Marshaling | 367 | - | - | - | - | - |
Runtime Callable Wrappers | 0 | - | - | - | - | - |
Socket Bytes Sent | 0 | - | - | - | - | - |
Socket Bytes Received | 0 | - | - | - | - | - |
Controls Created | 13 | - | - | - | - | - |
Brushes Created | 23 | - | - | - | - | - |
Pens Created | 8 | - | - | - | - | - |
Bitmaps Created | 16 | - | - | - | - | - |
Regions Created | 0 | - | - | - | - | - |
Fonts Created | 7 | - | - | - | - | - |
Graphics Created (FromImage) | 0 | - | - | - | - | - |
Graphics Created (CreateGraphics) | 0 | - | - | - | - | - |
Take care,
-- DK
[Edit: update counter table to fix errors]
[Edit: post titles]
Disclaimer(s):
This posting is provided "AS IS" with no warranties, and confers no rights.
Comments
- Anonymous
June 09, 2009
PingBack from http://insomniacuresite.info/story.php?id=4128