Welcome!

.NET Authors: Bruce Armstrong, Pat Romanski, Liz McMillan, Yeshim Deniz, Dmitry Sotnikov

Related Topics: .NET

.NET: Article

.NET Feature — The .NET Compact Framework Remote Performance Monitor

Optimizing your Device Application's Memory

Individual counters can then be selected for graphing. Figure 6 shows an example graph.

Analyzing the Data
Often times, the hardest part of performance analysis is getting the data you need to determine what's going wrong. Fortunately, RPM makes data gathering easy. All that's left is to analyze the numbers. In the next section, I'll describe how to use the memory and GC counters to diagnose the most common memory-related performance issues.

Per-Process Heap Sizes
When diagnosing performance issues, I typically start by looking at the size of the three largest heaps: the AppDomain heap, the JIT heap and the GC heap. The AppDomain heap and the JIT heap are directly related to the number of types your application loads and the number and size of the methods it calls. As such, there generally isn't much you can do to make these heaps smaller, outside of re-factoring your entire application. Generally, both the AppDomain and JIT heaps are well under 1MB. I've seen the JIT heap as large as 2.5 MB for very large applications, but that's definitely not the norm. Even though there isn't much you can do to minimize the size of these two heaps, it's often interesting to look at their combined sizes to get an indication of how much of the 32MB virtual address space is left over for other allocations such as those needed to store reference types in the GC heap. A large GC heap isn't necessarily a concern in and of itself, unless the heap is consuming so much of the 32MB space that little is left for other operations. A GC heap of 4 or 5 MB isn't uncommon.

The amount of activity, or churn, in the GC heap is often more of an issue than the size itself.

GC Activity
When taken together, the combination of the Garbage Collections, GC Latency Time, Managed Objects Allocated and Bytes Collected by GC counters will tell you if the GC is running more often and is spending more time than it would have to. Pay particular attention to the average GC latency. A high average GC latency is often an indicator that your application is continually creating a large number of managed objects. This trend can be verified using the Managed Objects Allocated counter.

If it looks like GC is an issue, the next step is to determine where the managed objects are coming from. The ratio between either Boxed Value Types or Managed String Objects Allocated and Managed Objects Allocated will tell if you the majority of objects are being creating "on your behalf" by operations such as boxing or string manipulations. If so, look for places in your code where you may be modifying instances of System.String or using collection classes that take instances of System.Object as a parameter (see my Garbage Collection article in the February issue of .NET Developer's Journal for more details).

Another important GC counter is the Objects Finalized counter. Objects with finalizers affect the GC because the memory occupied by the object cannot be freed until the finalizer has been run, so objects with finalizers are not freed until the next garbage collection after the object is no longer referenced. Effectively, objects with finalizers lengthen the time the memory they use is required. In extreme cases, this can put extra memory pressure on the system.

The Asterisk: Native Allocations
This article has focused on allocations made in memory controlled by the Compact Framework CLR. As we've seen there are tools available to give you a pretty good idea of how your application is behaving with respect to managed memory. However, there's another category of memory that we haven't considered yet: memory that is not controlled by the CLR, or what I'll call "native" memory.

Native memory is of interest because under most circumstances, requests for native memory are satisfied out of the same 32MB virtual address space that the CLR uses to manage the heaps it creates. All applications use at least some native memory because WindowsCE allocates various operating systems and windowing objects in your per-process address space as your application runs. Your application will use much more native memory if it interoperates with native code using either P/Invoke or COM. In these cases, memory will be taken from the 32MB virtual address space both to hold the code pages that make up the native DLLs and to satisfy any memory allocations made from within the native code. Because the Compact Framework is not directly aware of native memory allocations made in the process, the RPM does not report them. As a result, if all of the counters we've discussed in this article look fine, and you're still having memory problems, look to see if the native DLLs your application is using allocate significant amounts of native memory.

Summary
The .NET Compact Framework Remote Performance Monitor is a new diagnostic tool that can help you narrow down performance issues in your device applications. In this article I've focused on how RPM can help you identify areas within your application that can be tuned to make more efficient use of memory. RPM is integrated with the standard Windows Performance Monitor so you can graphically view memory allocation trends within your application. By using the various memory-related counters offered by the RPM, a developer can determine not only the extent to which services like garbage collection affect performance, but can also generally identify the source of their performance issues.

INSTALLING THE REMOTE PERFORMANCE MONITOR
The Remote Performance Monitor includes some files that reside on the desktop machine and some files that must be present on the device. The desktop components are installed automatically by version 2.0 Service Pack 1 setup program. After the installation completes, the RPM executable (netcfrpm.exe) is placed in the bin directory of Compact Framework SDK. On my machine, this directory is C:\Program Files\Microsoft.NET\SDK\CompactFramework\v2.0\bin.

The installation of the device-side components involves manually copying two files from the desktop machine to the device. The setup program places the device-side files in the same directory as the cab file that matches your processor type and operating system version. I have a Pocket PC 2003 SE device, so my device-side components are installed in C:\ProgramFiles\Microsoft. NET\SDK\CompactFramework\v2.0\WindowsCE\wce400\armv4. The two files you must copy are netcfrtl.dll and netcfl aunch.exe. Both of these files must be copied to the \windows directory of your device.
There are two issues you may run into when installing the device-side RPM components on Windows Mobile 5.0 devices:

  • Depending on the security confi guration chosen by the device manufacturer, you may see a security prompt on the device the first time you launch the RPM. This prompt appears because netcfrpm.dll is not digitally signed.
  • An additional installation step is necessary on Windows Mobile 5.0 devices to provision the device so the RPM can run. Provisioning involves copying the following XML text into a file and using the rapiconfig utility to send the XML file to the device:
- <wap-provisioningdoc>
  - <characteristic type="Metabase">
    - <characteristic type="RAPI\Windows\netcfrtl.dll\*">
    <parm name="rw-access" value="3" />
    <parm name="access-role" value="152" />
    <!-- 152 maps to "CARRIER_TPS | USER_AUTH | MANAGER"-->
    </characteristic>
  </characteristic>
</wap-provisioningdoc>

For example, if you paste the above XML text into a file named rpmprov.xml, you'd issue the command - rapiconfig /p rpmprov.xml - from your desktop machine to provision your device.

More Stories By Steven Pratschner

Steven Pratschner is the program manager for the .Net Compact Framework Common Language Runtime at Microsoft. Before working on the Compact Framework team, Steven spent several years working on the full .Net Framework. Steven has written articles and presented at numerous conferences on a variety of topics related to .Net-based programming. He is the author of the book Customizing the Common Language Runtime from Microsoft Press.

Comments (0)

Share your thoughts on this story.

Add your comment
You must be signed in to add a comment. Sign-in | Register

In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.