<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-US"><title type="html">Steven Pratschner's .Net CF WebLog</title><subtitle type="html" /><id>http://blogs.msdn.com/stevenpr/atom.xml</id><link rel="alternate" type="text/html" href="http://blogs.msdn.com/stevenpr/default.aspx" /><link rel="self" type="application/atom+xml" href="http://blogs.msdn.com/stevenpr/atom.xml" /><generator uri="http://communityserver.org" version="2.1.61025.2">Community Server</generator><updated>2007-08-14T10:53:00Z</updated><entry><title>The .Net Compact Framework Configuration Tool</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/stevenpr/archive/2008/05/13/the-net-compact-framework-configuration-tool.aspx" /><id>http://blogs.msdn.com/stevenpr/archive/2008/05/13/the-net-compact-framework-configuration-tool.aspx</id><published>2008-05-14T00:24:51Z</published><updated>2008-05-14T00:24:51Z</updated><content type="html">&lt;p&gt;&lt;font size="2"&gt;The .Net Compact Framework 3.5 &lt;/font&gt;&lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=C8174C14-A27D-4148-BF01-86C2E0953EAB&amp;amp;displaylang=en"&gt;&lt;font size="2"&gt;Power Toys&lt;/font&gt;&lt;/a&gt;&lt;font size="2"&gt; include a new utility called the NetCF Configuration Tool.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;The Configuration Tool is a diagnostic tool.&amp;#160; You won't typically use it in the course of everyday development, but it will come in handy for tasks like diagnosing failures related to device configuration and authoring configuration files.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;While the tool isn't targeted at your application's end users, they will be able to use it with your help should you need them to provide you with information needed to debug a problem remotely.&amp;#160; For this reason, the Configuration Tool runs directly on the mobile device instead of on a desktop machine connected to a device.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;After describing how to install the tool, I'll discuss its four main functional areas:&lt;/font&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;font size="2"&gt;Displaying which versions of NetCF are installed&lt;/font&gt; &lt;/li&gt;    &lt;li&gt;&lt;font size="2"&gt;Displaying the contents of the Global Assembly Cache&lt;/font&gt; &lt;/li&gt;    &lt;li&gt;&lt;font size="2"&gt;Authoring device.config files&lt;/font&gt; &lt;/li&gt;    &lt;li&gt;&lt;font size="2"&gt;Authoring application configuration files&lt;/font&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h2&gt;Installing the Configuration Tool&lt;/h2&gt;  &lt;p&gt;&lt;font size="2"&gt;The Configuration Tool isn't automatically installed on the device when you install the Power Toys.&amp;#160; Instead, you must copy it to your device manually. &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;Fortunately there's only one file to copy: &lt;font face="Courier New" color="#004080"&gt;NetCFcfg.exe&lt;/font&gt;. This file is OS and processor-specific so you'll find it under the appropriate WindowsCE directory in the .Net Compact Framework SDK.&amp;#160; I'm running a WindowsMobile 5.0 device, so the Configuration Tool executable for my device is in: &lt;font face="Courier New" color="#004080"&gt;C:\Program Files\Microsoft.NET\SDK\CompactFramework\v3.5\WindowsCE\wce500\armv4i&lt;/font&gt;&lt;/font&gt; &lt;font size="2"&gt;on my desktop machine.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;It doesn't matter which directory you put the file in on your device.&amp;#160; I usually put it in the &lt;font face="Courier New" color="#004080"&gt;\windows&lt;/font&gt; directory but you can deploy the file to any location you please.&lt;/font&gt;&lt;/p&gt;  &lt;h2&gt;The About tab&lt;/h2&gt;  &lt;p&gt;&lt;font size="2"&gt;The &amp;quot;About tab&amp;quot; describes which versions of NetCF are installed on a device.&amp;#160; This is the tab that is displayed when you first launch the Configuration Tool:&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://farm3.static.flickr.com/2393/2478556401_7b9399ba4e_o.jpg" /&gt; &lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;It's not unusual to have more than one version of NetCF installed on a device. Most all Windows Mobile and WindowsCE devices come with a version of NetCF in ROM.&amp;#160; Another version is often installed in RAM to support an application that requires a newer version of NetCF than the version that came with the device.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;When multiple versions of NetCF are installed, it's not always obvious which version is being used to run your application.&amp;#160; I've seen several cases where confusion results because an application is running with a different version than expected (see &amp;quot;&lt;a href="http://blogs.msdn.com/stevenpr/archive/2008/03/11/promoting-all-net-compact-framework-applications-on-a-device-using-device-config.aspx"&gt;promoting an application&lt;/a&gt;&amp;quot; for a general description of the rules used to determine which version of NetCF will be used to run an application).&amp;#160; For example, remote tools like the &lt;a href="http://blogs.msdn.com/stevenpr/archive/2008/05/08/the-clr-profiler-for-the-net-compact-framework-series-index.aspx"&gt;CLRProfiler&lt;/a&gt; and &lt;a href="http://blogs.msdn.com/stevenpr/archive/2007/10/26/what-s-new-in-the-remote-performance-monitor-for-net-compact-framework-3-5.aspx"&gt;Remote Performance Monitor&lt;/a&gt; launch an application on device in order to profile it or gather other performance statistics.&amp;#160; If your application is launched with a version of NetCF other than the one the tool is expecting, the application may start but the tool won't be able to gather the diagnostic information it is looking for.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;Knowing which versions of NetCF are installed on the device, which version was used to build your application, and the rules used to determine which version will be used to run your application can help you determine whether any unexpected behavior you are seeing results from the &amp;quot;wrong version of NetCF&amp;quot; problem.&lt;/font&gt;&lt;/p&gt;  &lt;h2&gt;The GAC tab&lt;/h2&gt;  &lt;p&gt;&lt;font size="2"&gt;The GAC tab lists the assemblies installed in the Global Assembly Cache:&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://farm3.static.flickr.com/2382/2479375148_e85ff23040_o.jpg" /&gt; &lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;It helps to know the contents of the GAC when diagnosing assembly load failures.&amp;#160; It may be you think an assembly is in the GAC when it isn't, or NetCF may load an assembly from the GAC when you don't expect it to.&amp;#160; If you encounter a failure to load an assembly, use &lt;a href="http://blogs.msdn.com/stevenpr/archive/2005/02/28/381744.aspx"&gt;Loader Logging&lt;/a&gt; to find out why, then check the contents of the GAC using the Configuration Tool if the failure looks related to the GAC.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h2&gt;The Device Policy tab&lt;/h2&gt;  &lt;p&gt;&lt;font size="2"&gt;In a previous post I described how to use &lt;a href="http://blogs.msdn.com/stevenpr/archive/2008/03/11/promoting-all-net-compact-framework-applications-on-a-device-using-device-config.aspx"&gt;device.config&lt;/a&gt; to cause all applications on a device to run with a given version of NetCF.&amp;#160; The Configuration Tool enables you to edit device.config using a GUI rather than having to modify the XML by hand.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://farm3.static.flickr.com/2349/2486504869_8609701692_o.jpg" /&gt; &lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;The Device Policy tab let's you choose a version of NetCF to run all &amp;quot;unconfigured&amp;quot; applications on the device.&amp;#160; By &amp;quot;unconfigured&amp;quot; I mean all applications that do not have an application configuration file that contains a &lt;font face="Courier New" color="#004080"&gt;supportedRuntime&lt;/font&gt; element.&amp;#160; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;In addition to the installed versions of NetCF, you can also select the value &amp;quot;Default&amp;quot;.&amp;#160; Doing so will remove all &lt;font face="Courier New" color="#004080"&gt;supportedRuntime&lt;/font&gt; elements from device.config causing the device to revert to its default behavior for selecting a runtime. &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;Keep in mind that not all values you select on this tab are &amp;quot;valid&amp;quot; for all applications.&amp;#160; For example,&amp;#160; if I chose 1.0.4292 in the example above, no applications built with later versions of NetCF would run (unless they had configurations files of their own that overrode the device-wide setting).&lt;/font&gt;&lt;/p&gt;  &lt;h2&gt;The Application Policy tab&lt;/h2&gt;  &lt;p&gt;&lt;font size="2"&gt;In addition to specifying device-wide policy using the Device Policy tab, you can also specify which version of NetCF should be used to run a specific application by using the Application Policy tab.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://farm3.static.flickr.com/2351/2487321046_9a525db7fd_o.jpg" /&gt; &lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;The top combo box on the Application Policy tab is pre-populated with all NetCF applications that are installed on the device.&amp;#160; After selecting an application, use the lower combo box to select a version of NetCF to run the application.&amp;#160; Under the covers this dialog is adding (or removing) &lt;font face="courier " color="#004080"&gt;supportedRuntime&lt;/font&gt; elements from your application's configuration file.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;Any value chosen using the Application Policy tab overrides values chosen using the Device Policy tab.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;Thanks,&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;Steven&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;This posting is provided &amp;quot;AS IS&amp;quot; with no warranties, and confers no rights.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8501794" width="1" height="1"&gt;</content><author><name>stevenpr</name><uri>http://blogs.msdn.com/members/stevenpr.aspx</uri></author></entry><entry><title>The CLR Profiler for the .Net Compact Framework Series Index</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/stevenpr/archive/2008/05/08/the-clr-profiler-for-the-net-compact-framework-series-index.aspx" /><id>http://blogs.msdn.com/stevenpr/archive/2008/05/08/the-clr-profiler-for-the-net-compact-framework-series-index.aspx</id><published>2008-05-09T00:04:17Z</published><updated>2008-05-09T00:04:17Z</updated><content type="html">&lt;p&gt;&lt;font size="2"&gt;I've completed all that I had planned to write (at least for now) about how to use the CLRProfiler with NetCF.&lt;/font&gt;&amp;#160; &lt;font size="2"&gt;Here's a brief explanation and a link to each post the series:&lt;/font&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://blogs.msdn.com/stevenpr/archive/2007/10/17/the-clrprofiler-for-the-net-compact-framework-part-1-getting-started.aspx"&gt;&lt;font size="2"&gt;Part I, Getting Started.&lt;/font&gt;&lt;/a&gt;&lt;font size="2"&gt; Describes how to install the profiler, launch an application, and begin collecting profiling data.&lt;/font&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/stevenpr/archive/2007/10/18/the-clrprofiler-for-the-net-compact-framework-part-ii-histograms-and-show-who-allocated.aspx"&gt;&lt;font size="2"&gt;Part II, Histograms and &amp;quot;Show Who Allocated&amp;quot;.&lt;/font&gt;&lt;/a&gt;&lt;font size="2"&gt; The profiler displays various histograms you can use to determine the types and number of objects your application is allocating.&amp;#160; You can also determine what methods in your application cause which types to get allocated.&lt;/font&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/stevenpr/archive/2007/11/28/the-clrprofler-for-the-net-compact-framework-part-iii-the-timeline-view.aspx"&gt;&lt;font size="2"&gt;Part III, The Timeline View.&lt;/font&gt;&lt;/a&gt;&lt;font size="2"&gt; The timeline view shows the state of the GC heap over the lifetime of your application.&lt;/font&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/stevenpr/archive/2008/02/12/the-clrprofiler-for-the-net-compact-framework-part-iv-the-call-tree-view.aspx"&gt;&lt;font size="2"&gt;Part IV, The Call Tree View.&lt;/font&gt;&lt;/a&gt;&lt;font size="2"&gt; Detailed information about every method call and every object allocation is shown in the Call Tree View.&lt;/font&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/stevenpr/archive/2008/04/22/the-clrprofiler-for-the-net-compact-framework-part-v-controlling-the-profiler-programmatically.aspx"&gt;&lt;font size="2"&gt;Part V, Controlling the Profiler Programmatically.&lt;/font&gt;&lt;/a&gt;&lt;font size="2"&gt; The CLRProfiler generates a large amount of data and significantly slows down your application.&amp;#160; You can programmatically control when the profiler runs using an API that you call from your application.&amp;#160; This API also allows you to insert comments into the profile data and to take a snapshot of the GC on demand.&lt;/font&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;font size="2"&gt;Thanks,&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;Steven&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;This posting is provided &amp;quot;AS IS&amp;quot; with no warranties, and confers no rights.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8474552" width="1" height="1"&gt;</content><author><name>stevenpr</name><uri>http://blogs.msdn.com/members/stevenpr.aspx</uri></author></entry><entry><title>The CLRProfiler for the .Net Compact Framework, Part V: Controlling the profiler programmatically</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/stevenpr/archive/2008/04/22/the-clrprofiler-for-the-net-compact-framework-part-v-controlling-the-profiler-programmatically.aspx" /><id>http://blogs.msdn.com/stevenpr/archive/2008/04/22/the-clrprofiler-for-the-net-compact-framework-part-v-controlling-the-profiler-programmatically.aspx</id><published>2008-04-23T03:58:46Z</published><updated>2008-04-23T03:58:46Z</updated><content type="html">&lt;p&gt;&lt;font size="2"&gt;If you've used the CLRProfiler for NetCF you've probably noticed that your application runs much slower when being profiled.&amp;#160; You likely have also seen the huge amount of data the profiler generates, even for relatively simple applications.&amp;#160; The time it takes the profiler to run coupled with the volume of data it creates can sometimes make the profiler impractical to use.&amp;#160; For example, I've had customers tell me that it can take several minutes to start an application while profiling.&amp;#160; If it takes you several more minutes just to navigate to the portion of the application you'd like to profile, it can quickly become extremely frustrating.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;The CLRProfiler ships with an additional assembly you can reference and call from your application to control the profiler while your application is running.&amp;#160; This assembly, called &lt;font face="Courier New" color="#0000ff"&gt;NetCFCLRProfilerControl&lt;/font&gt; contains APIs you can use to start and stop profiling, insert comments into the profiling log, dump the contents of the GC heap on demand, and so on.&amp;#160; The ability to control when the profiler collects data enables you to profile only the sections of your application you want to, rather than having the profiler collect data all the time.&amp;#160; In this way, your application will start faster and there will be less data to sift through later.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;In this post I'll describe how to use the APIs provided by the &lt;font face="Courier New" color="#0000ff"&gt;NetCFCLRProfilerControl&lt;/font&gt;.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;  &lt;h2&gt;Using the NetCFCLRProfilerControl Assembly&lt;/h2&gt;  &lt;p&gt;&lt;font size="2"&gt;The following steps are required to use &lt;font face="Courier New" color="#0000ff"&gt;NetCFCLRProfilerControl&lt;/font&gt; from your application:&lt;/font&gt;&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;font size="2"&gt;Reference &lt;font face="Courier New" color="#0000ff"&gt;NetCFCLRProfilerControl&lt;/font&gt; in your Visual Studio project.&lt;/font&gt;&lt;/li&gt;    &lt;li&gt;&lt;font size="2"&gt;Add code to your application to call the APIs.&lt;/font&gt;&lt;/li&gt;    &lt;li&gt;&lt;font size="2"&gt;Deploy &lt;font face="Courier New" color="#0000ff"&gt;NetCFCLRProfilerControl&lt;/font&gt; along with your application.&lt;/font&gt;&lt;/li&gt;    &lt;li&gt;&lt;font size="2"&gt;Start your application using the CLRProfiler.&lt;/font&gt;&lt;/li&gt; &lt;/ol&gt;  &lt;h3&gt;Referencing NetCFCLRProfilerControl&lt;/h3&gt;  &lt;p&gt;&lt;font size="2"&gt;&lt;font face="Courier New" color="#0000ff"&gt;NetCFCLRProfilerControl&lt;/font&gt; is installed on the desktop machine in same directory as the &lt;font face="Courier New" color="#0000ff"&gt;NetCFCLRProfiler&lt;/font&gt; executable.&amp;#160; On my machine the files are in &lt;font face="Courier New" color="#0000ff"&gt;C:\Program Files\Microsoft.NET\SDK\CompactFramework\v3.5\bin.&amp;#160; &lt;/font&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;You'll need to add a reference from your application to &lt;font face="Courier New" color="#0000ff"&gt;NetCFCLRProfilerControl&lt;/font&gt; to use its APIs.&amp;#160; If you're using Visual Studio you can add this reference using the standard &amp;quot;Add Reference...&amp;quot; dialog.&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;/p&gt;  &lt;h3&gt;Public APIs&lt;/h3&gt;  &lt;p&gt;&lt;font size="2"&gt;&lt;font face="Courier New" color="#0000ff"&gt;NetCFCLRProfilerControl&lt;/font&gt; contains one public class called &lt;font face="Courier New" color="#0000ff"&gt;CLRProfilerControl&lt;/font&gt; which contains the following public static members:&lt;/font&gt;&lt;/p&gt;  &lt;table cellspacing="0" cellpadding="2" width="606" border="2"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="229"&gt;&lt;font color="#0000a0" size="2"&gt;Member&lt;/font&gt;&lt;/td&gt;        &lt;td valign="top" width="370"&gt;&lt;font color="#0000a0" size="2"&gt;Notes&lt;/font&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="229"&gt;         &lt;p&gt;&lt;font face="Courier New" color="#0000ff" size="2"&gt;bool ProcessIsUnderProfiler { get; }&lt;/font&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="370"&gt;&lt;font size="2"&gt;Returns true if your application was launched using the CLRProfiler.&amp;#160; Note that this is independent of whether the profiler is actually logging allocations or calls at the time.           &lt;br /&gt;&lt;/font&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="229"&gt;         &lt;p&gt;&lt;font face="Courier New" color="#0000ff" size="2"&gt;bool AllocationLoggingActive { set; get; }&lt;/font&gt; &lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="370"&gt;&lt;font size="2"&gt;A boolean property that controls whether the profiler logs managed allocations.&lt;/font&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="229"&gt;         &lt;p&gt;&lt;font face="Courier New" color="#0000ff" size="2"&gt;bool CallLoggingActive { set; get; }&lt;/font&gt; &lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="370"&gt;&lt;font size="2"&gt;A boolean property that controls whether the profiler logs method calls.&lt;/font&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="229"&gt;         &lt;p&gt;&lt;font face="Courier New" color="#0000ff" size="2"&gt;void LogWriteLine(string comment)&lt;/font&gt;&lt;/p&gt;          &lt;p&gt;&lt;font face="Courier New" color="#0000ff" size="2"&gt;void LogWriteLine(string format, params object[] args)&lt;/font&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="370"&gt;&lt;font size="2"&gt;Enables you to insert comments into the profiling log.&amp;#160; These comments show up in the various profiler views to help you narrow down exactly where in your application certain allocations or calls were made.&amp;#160; See the example later in this post.&lt;/font&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="229"&gt;         &lt;p&gt;&lt;font face="Courier New" color="#0000ff" size="2"&gt;void DumpHeap()&lt;/font&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="370"&gt;&lt;font size="2"&gt;Causes the profiler to display a graphical view of the GC heap.&amp;#160; Individual views will also show up on the profiler's summary form when the application exits.&lt;/font&gt;&lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h3&gt;Deploying your application&lt;/h3&gt;  &lt;p&gt;&lt;font size="2"&gt;&lt;font face="Courier New" color="#0000ff"&gt;NetCFCLRProfilerControl&lt;/font&gt; is not installed on the device automatically.&amp;#160; You'll need to deploy it along with your application.&amp;#160; It's probably easiest to deploy &lt;font face="Courier New" color="#0000ff"&gt;NetCFCLRProfilerControl&lt;/font&gt; to the same directory as your application but you can also install it in the GAC if you prefer.&lt;/font&gt;&lt;/p&gt;  &lt;h3&gt;Launching your application&lt;/h3&gt;  &lt;p&gt;&lt;font size="2"&gt;The APIs provided by &lt;font face="Courier New" color="#0000ff"&gt;NetCFCLRProfilerControl&lt;/font&gt; have no effect if your application isn't started using the CLRProfiler.&amp;#160; However, assuming you are going to use the APIs to control when the profiler logs allocations and/or calls, be sure to clear the relevant checkboxes on the profiler's main form before launching your application (otherwise you'll be logging all the stuff you wanted to prevent in the first place!).&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://farm4.static.flickr.com/3044/2434621505_5a6a359be3_o.jpg" /&gt; &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;After clearing the checkboxes, start your application using the profiler as you always have.&amp;#160; The actions of the profiler will now be controlled by your application instead of the CLRProfiler's user interface.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;  &lt;h2&gt;Turning profiling on and off&lt;/h2&gt;  &lt;p&gt;&lt;font size="2"&gt;Assuming you've started your application with the &amp;quot;Profile&amp;quot; checkboxes on the profiler's main form cleared, no logging of allocations or calls will occur.&amp;#160; You can turn profiling on using the &lt;font face="Courier New" color="#0000ff"&gt;AllocationLoggingActive&lt;/font&gt; and &lt;font face="Courier New" color="#0000ff"&gt;CallLoggingActive&lt;/font&gt; properties.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;The following example turns allocation logging on just before entering a loop, then turns logging back off when the loop completes:&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" color="#0000ff" size="2"&gt;private void btnCheckOut_Click(object sender, EventArgs e)     &lt;br /&gt;{      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;strong&gt;CLRProfilerControl.AllocationLoggingActive = true;&lt;/strong&gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; for (int i = 0; i &amp;lt; 20; i++)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; m_cart.ProcessCart();      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;strong&gt;CLRProfilerControl.AllocationLoggingActive = false;       &lt;br /&gt;&lt;/strong&gt;}&lt;/font&gt;&lt;/p&gt;  &lt;h2&gt;Inserting comments into the profiling log&lt;/h2&gt;  &lt;p&gt;&lt;font size="2"&gt;The ability to insert comments into the profiling log is a cool feature that enables you to place your own visual markers into some of the profiler's graphical views.&amp;#160; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;Here's an example that inserts comments denoting the beginning and end of the execution of a loop:&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" color="#0000ff" size="2"&gt;private void btnCheckOut_Click(object sender, EventArgs e)     &lt;br /&gt;{      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;strong&gt;CLRProfilerControl.LogWriteLine(&amp;quot;Before ProcessCart loop&amp;quot;);&lt;/strong&gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; for (int i = 0; i &amp;lt; 20; i++)      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; m_cart.ProcessCart();      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;strong&gt;CLRProfilerControl.LogWriteLine(&amp;quot;After ProcessCart loop&amp;quot;);&lt;/strong&gt;      &lt;br /&gt;}&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;After the application exits, your comments show up in several places in the CLRProfiler UI.&amp;#160; First, the summary screen includes a button that brings up a window giving the timestamp of each comment.&amp;#160; You can use this as a rudimentary timing mechanism in your application:&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;&lt;img src="http://farm4.static.flickr.com/3067/2435477454_cd9a29e505_o.jpg" /&gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;The comments also show up in various views throughout the UI&amp;#160; For example, in the Timeline View, the comments show up as vertical green lines that indicate the time at which the comment was logged.&amp;#160; You can see the text of a given comment by hovering the house over its green line.&amp;#160; This allows you to see the state of the GC heap between different points of interest as your application ran.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;&lt;img src="http://farm3.static.flickr.com/2348/2434661163_2513122be5.jpg" /&gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;  &lt;h2&gt;Dumping the GC Heap&lt;/h2&gt;  &lt;p&gt;&lt;font size="2"&gt;The final feature available via &lt;font face="Courier New" color="#0000ff"&gt;NetCFCLRProfilerControl&lt;/font&gt; is the ability to take a snapshot of the GC heap on demand.&amp;#160; The &lt;font face="Courier New" color="#0000ff"&gt;DumpHeap&lt;/font&gt; method causes a heap view to be displayed immediately.&amp;#160; You can also access all the heap views taken while the app ran from the Summary View after the application exits.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;Thanks,&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;Steven&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;This posting is provided &amp;quot;AS IS&amp;quot; with no warranties, and confers no rights.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8417658" width="1" height="1"&gt;</content><author><name>stevenpr</name><uri>http://blogs.msdn.com/members/stevenpr.aspx</uri></author></entry><entry><title>Promoting all .Net Compact Framework Applications on a device using device.config</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/stevenpr/archive/2008/03/11/promoting-all-net-compact-framework-applications-on-a-device-using-device-config.aspx" /><id>http://blogs.msdn.com/stevenpr/archive/2008/03/11/promoting-all-net-compact-framework-applications-on-a-device-using-device-config.aspx</id><published>2008-03-12T03:01:01Z</published><updated>2008-03-12T03:01:01Z</updated><content type="html">&lt;p&gt;&lt;font size="2"&gt;By default, a managed device application is run with the version of the .Net Compact Framework it was built with.&amp;#160; Only if that version is not present on the device will we &amp;quot;promote&amp;quot; the application to run with the latest installed version.&amp;#160; This policy is considered safe and conservative because it isolates applications from unintended compatibility changes that may be introduced in new version of the Framework, at least in the most common scenario.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;However, there are times when you may want to run an application with a version of NetCF other than the one it was built with.&amp;#160; For example you may find that a newer version of NetCF performs better and is more stable than a previous version so you'd like to take advantage of those improvements without having to rebuild your application.&amp;#160; Several previous blog posts (see &lt;a title="http://blogs.msdn.com/davidklinems/archive/2005/11/09/491113.aspx" href="http://blogs.msdn.com/davidklinems/archive/2005/11/09/491113.aspx"&gt;http://blogs.msdn.com/davidklinems/archive/2005/11/09/491113.aspx&lt;/a&gt;) have shown how to do this using an application configuration file.&amp;#160; This approach is manageable as long as you only have a few applications to promote.&amp;#160; But if you'd like to promote a large number of applications it can quickly become a hassle to author all these configuration files and manage their deployment and updates.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;Fortunately, version 3.5 of the Compact Framework lets you promote all applications on a device using a single device-wide configuration file.&amp;#160; The syntax of this configuration file is the same as that used in the application configuration file: you specify the version of NetCF you'd like to run all applications with using the &lt;font face="Courier New" color="#004080"&gt;supportedRuntime&lt;/font&gt; element.&amp;#160; The device-wide configuration file must be called &lt;font face="Courier New" color="#004080"&gt;device.config&lt;/font&gt; and must be located in the &lt;font face="Courier New" color="#004080"&gt;\windows&lt;/font&gt; directory.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;Here's the contents of a sample &lt;font face="Courier New" color="#004080"&gt;device.config&lt;/font&gt; that will cause all applications to be run with .Net Compact Framework version 3.5:&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" color="#004080" size="2"&gt;&amp;lt;configuration&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;startup&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;supportedRuntime version=&amp;quot;v3.5.7238&amp;quot;/&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/startup&amp;gt;       &lt;br /&gt;&amp;lt;/configuration&amp;gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New" color="#004080" size="2"&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="ver" color="#000000" size="2"&gt;There's one more case to consider.&amp;#160; Suppose you've used &lt;font face="Courier New" color="#004080"&gt;device.config&lt;/font&gt; to promote all your applications only to discover that one of your applications doesn't work properly.&amp;#160; In this scenario you'd want to &amp;quot;roll back&amp;quot; just that one application to the version it was built with.&amp;#160; You'd do this by authoring an application configuration file for that application.&amp;#160; Any &lt;font face="Courier New" color="#004080"&gt;supportedRuntime&lt;/font&gt; settings present in application configuration files will override the settings specified in &lt;font face="Courier New" color="#004080"&gt;device.config&lt;/font&gt; thus giving you a quick way to opt-out of your global policy.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#000000" size="2"&gt;Thanks,&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#000000" size="2"&gt;Steven&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;This posting is provided &amp;quot;AS IS&amp;quot; with no warranties, and confers no rights.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8163618" width="1" height="1"&gt;</content><author><name>stevenpr</name><uri>http://blogs.msdn.com/members/stevenpr.aspx</uri></author></entry><entry><title>The CLRProfiler for the .Net Compact Framework, Part IV: The Call Tree View</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/stevenpr/archive/2008/02/12/the-clrprofiler-for-the-net-compact-framework-part-iv-the-call-tree-view.aspx" /><id>http://blogs.msdn.com/stevenpr/archive/2008/02/12/the-clrprofiler-for-the-net-compact-framework-part-iv-the-call-tree-view.aspx</id><published>2008-02-12T21:10:23Z</published><updated>2008-02-12T21:10:23Z</updated><content type="html">&lt;p&gt;&lt;font size="2"&gt;This series of posts provides an introduction to using the CLRProfiler for the .Net Compact Framework.&amp;#160; In previous posts (&lt;a href="http://blogs.msdn.com/stevenpr/archive/2007/10/17/the-clrprofiler-for-the-net-compact-framework-part-1-getting-started.aspx"&gt;part 1&lt;/a&gt;, &lt;a href="http://blogs.msdn.com/stevenpr/archive/2007/10/18/the-clrprofiler-for-the-net-compact-framework-part-ii-histograms-and-show-who-allocated.aspx"&gt;part 2&lt;/a&gt;, and &lt;a href="http://blogs.msdn.com/stevenpr/archive/2007/11/28/the-clrprofler-for-the-net-compact-framework-part-iii-the-timeline-view.aspx"&gt;part 3&lt;/a&gt;) we've looked at various profiler features as we try to solve a performance problem with a sample application.&amp;#160; So far, we've learned that our performance problem is due to excessive boxing of value types.&amp;#160; We've also learned what type of objects we are boxing and what methods in the sample are causing the boxing to occur.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;In some cases, knowing which method is causing the problem is all you need, especially if the method is small and straightforward.&amp;#160; However, there are cases where even more detail is needed.&amp;#160; In this post I'll use the Call Tree View to determine the &lt;em&gt;exact line of source code&lt;/em&gt; that is causing my performance issue!&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;After you've finished profiling, you can bring up the Call Tree View from the summary page:&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://farm3.static.flickr.com/2002/2231705450_aee3a468b8.jpg" /&gt; &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h1&gt;The Call Tree View&lt;/h1&gt;  &lt;p&gt;&lt;font size="2"&gt;The Call Tree View shows every allocation made as a result of every method call.&amp;#160; For all but the simplest programs the Call Tree View contains a huge amount of data.&amp;#160; Fortunately, navigating through all this data isn't very hard once you get used to a few tricks.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;Method calls are shown in black and object allocations are shown in green.&amp;#160; For example, the following picture shows the initial state of the Call Tree View.&amp;#160; You can see that only one method (the program's &lt;font face="Courier New"&gt;Main&lt;/font&gt; method) has been called at this outermost level.&amp;#160; You can also see that several allocations have already been made.&amp;#160; These initial allocations are made by the CLR just before it starts executing a program.&amp;#160; As you can see, these initial allocations represent several of the common exception types as well as the initial Application Domain.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://farm3.static.flickr.com/2125/2230902073_7c65acbb7e.jpg" /&gt; &lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;Along with the individual method calls and object allocations, the Call Tree View also shows summary statistics such as the number of method calls that result from a given call, the number of bytes and objects allocated by a given call and so on.&amp;#160; You can sort the data either by number of calls or by the amount of memory allocated.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;As you start to expand the tree, you'll notice that one child node at each level is highlighted in bold.&amp;#160; The highlighted node represents the method that has allocated the most memory (or generated the most calls, depending on your sort preference).&amp;#160; This is the key to drilling into the data quickly - just follow the highlighted nodes until you find the method you are looking for.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h2&gt;Back to the Example&lt;/h2&gt;  &lt;p&gt;&lt;font size="2"&gt;In previous posts we've established that the objects we are boxing are of type &lt;font face="Courier New"&gt;Box.Block&lt;/font&gt; and that the boxing is occurring in calls to &lt;font face="Courier New"&gt;RotateGameBlocks&lt;/font&gt; and &lt;font face="Courier New"&gt;InitializeGameBlocks&lt;/font&gt;.&amp;#160; By drilling through the data in the Call Tree View we can find out exactly which line of code in &lt;font face="Courier New"&gt;RotateGameBlocks&lt;/font&gt; (or &lt;font face="Courier New"&gt;InitializeGameBlocks&lt;/font&gt;) is causing the boxing to occur.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;The following picture shows the result of following the highlighted notes until I have found the &lt;font face="Courier New"&gt;RotateGameBlocks&lt;/font&gt; method.&amp;#160; Some of the methods in the tree look familiar, like &lt;font face="Courier New"&gt;Main&lt;/font&gt;, and &lt;font face="Courier New"&gt;Application.Run&lt;/font&gt;, but many methods don't.&amp;#160; Method names that you don't recognize are likely part of NetCF's internal implementation.&amp;#160; For example, methods that contain &amp;quot;&lt;font face="Courier New"&gt;AGL&lt;/font&gt;&amp;quot; in their name are part of NetCF's implementation of Windows Forms. &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;&lt;img src="http://farm3.static.flickr.com/2147/2230902115_e5b90213f5.jpg" /&gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;When looking at the child nodes of &lt;font face="Courier New"&gt;RotateGameBlocks&lt;/font&gt;, we see a green line representing the allocations of &lt;font face="Courier New"&gt;Box.Block&lt;/font&gt;.&amp;#160; The Objects column tells us that a call to &lt;font face="Courier New"&gt;RotateGameBlocks&lt;/font&gt; causes 14,400 instances of &lt;font face="Courier New"&gt;Box.Block&lt;/font&gt; to be allocated.&amp;#160; Furthermore, we can see that &lt;font face="Courier New"&gt;RotateGameBlocks&lt;/font&gt; calls &lt;font face="Courier New"&gt;ArrayList.set_Item&lt;/font&gt; 14,400 times.&amp;#160; The fact that the number of calls to &lt;font face="Courier New"&gt;ArrayList.set_Item&lt;/font&gt; and the number of instances of &lt;font face="Courier New"&gt;Box.Block&lt;/font&gt; that are allocated are the same indicates that the calling &lt;font face="courier "&gt;ArrayList.set_Item&lt;/font&gt; is the line in my sample that is causing our boxing to occur.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;In my next post I'll describe a set of managed APIs you can use to control profiling programmatically.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;Thanks,&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;Steven&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="1"&gt;This posting is provided &amp;quot;AS IS&amp;quot; with no warranties, and confers no rights.&lt;/font&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=7649678" width="1" height="1"&gt;</content><author><name>stevenpr</name><uri>http://blogs.msdn.com/members/stevenpr.aspx</uri></author><category term="Diagnostics" scheme="http://blogs.msdn.com/stevenpr/archive/tags/Diagnostics/default.aspx" /></entry><entry><title>PowerToys for the .Net Compact Framework version 3.5 now released!</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/stevenpr/archive/2007/12/10/powertoys-for-the-net-compact-framework-version-3-5-now-released.aspx" /><id>http://blogs.msdn.com/stevenpr/archive/2007/12/10/powertoys-for-the-net-compact-framework-version-3-5-now-released.aspx</id><published>2007-12-11T02:21:57Z</published><updated>2007-12-11T02:21:57Z</updated><content type="html">&lt;p&gt;&lt;font size="2"&gt;We've just released the &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=C8174C14-A27D-4148-BF01-86C2E0953EAB&amp;amp;displaylang=en"&gt;final 3.5 version of the PowerToys for NetCF&lt;/a&gt; to the web.&amp;#160; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;You'll need to install the 3.5 NetCF runtime on your device to use these tools.&amp;#160; For now, you can get the correct runtime by installing &lt;a href="http://msdn.microsoft.com/"&gt;Visual Studio 2008&lt;/a&gt;.&amp;#160; In a few weeks we hope to post a standalone install for NetCF 3.5.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;The PowerToys release includes all the tools you need to diagnose issues in your .Net device applications, including the &lt;a href="http://blogs.msdn.com/stevenpr/archive/2007/10/26/what-s-new-in-the-remote-performance-monitor-for-net-compact-framework-3-5.aspx"&gt;Remote Performance Monitor&lt;/a&gt;, &lt;a href="http://blogs.msdn.com/stevenpr/archive/2007/10/17/the-clrprofiler-for-the-net-compact-framework-part-1-getting-started.aspx"&gt;CLR Profiler&lt;/a&gt;, the &lt;a href="http://blogs.msdn.com/danhorbatt/archive/2007/11/01/remote-logging-wcf-on-net-compact-framework.aspx"&gt;Logging Utility&lt;/a&gt; and more...&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;Thanks,&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;Steven&lt;/font&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;This posting is provided &amp;quot;AS IS&amp;quot; with no warranties, and confers no rights&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=6728543" width="1" height="1"&gt;</content><author><name>stevenpr</name><uri>http://blogs.msdn.com/members/stevenpr.aspx</uri></author></entry><entry><title>The CLRProfler for the .Net Compact Framework, Part III: The Timeline View</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/stevenpr/archive/2007/11/28/the-clrprofler-for-the-net-compact-framework-part-iii-the-timeline-view.aspx" /><id>http://blogs.msdn.com/stevenpr/archive/2007/11/28/the-clrprofler-for-the-net-compact-framework-part-iii-the-timeline-view.aspx</id><published>2007-11-28T22:31:37Z</published><updated>2007-11-28T22:31:37Z</updated><content type="html">&lt;p&gt;&lt;font size="2"&gt;In the first two parts of this series (&lt;a href="http://blogs.msdn.com/stevenpr/archive/2007/10/17/the-clrprofiler-for-the-net-compact-framework-part-1-getting-started.aspx"&gt;part 1&lt;/a&gt; and &lt;a href="http://blogs.msdn.com/stevenpr/archive/2007/10/18/the-clrprofiler-for-the-net-compact-framework-part-ii-histograms-and-show-who-allocated.aspx"&gt;part 2&lt;/a&gt;) I described how to get started using the CLRProfiler and how to use the histograms and the &amp;quot;Show Who Allocated&amp;quot; view to see what types of objects you're allocating and to determine where in your application the allocations are occurring.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;In this post I'll talk about my favorite view: the Timeline view.&amp;#xA0; I like the Timeline view because it lets you look at the contents of the GC heap over time.&amp;#xA0; Using this view you can see not only where in your application you are allocating objects, but when. You can also see which objects are collected each time the GC ran.&amp;#xA0; By including a time dimension, the Timeline view combined with &amp;quot;Show Who Allocated&amp;quot; can give you a complete picture of how the use of managed memory varies as your application runs.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;After you've completed profiling, you can launch the Timeline view from the Summary page:&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;img id="id" src="http://farm3.static.flickr.com/2260/2072014366_1a62e96f25.jpg" /&gt; &lt;/p&gt;  &lt;p&gt;&amp;#xA0;&lt;/p&gt;  &lt;h1&gt;The Timeline View&lt;/h1&gt;  &lt;p&gt;&lt;font size="2"&gt;The Timeline view has two panes.&amp;#xA0; The right hand pane is the legend and the left hand pane is the contents of the heap.&amp;#xA0; As with the histograms we looked at in part 2, the colors in the legend describe the types of objects present in the heap.&amp;#xA0; Free space in the heap is always white:&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;img id="id" src="http://farm3.static.flickr.com/2183/2072014404_edee84895b.jpg" /&gt; &lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;The horizontal axis in this view represents time.&amp;#xA0; If you look at the axis you can see when each GC occurred as indicated by the vertical blue markers.&amp;#xA0; By correlating each GC with the contents of the heap displayed above you can get a sense for which objects were freed in each collection.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;&lt;font color="#800000"&gt;&lt;strong&gt;Note:&lt;/strong&gt; &lt;em&gt;You may notice that each GC is labeled with a generation.&amp;#xA0; The Compact Framework's garbage collector doesn't have the notion of generations so these markers are an artifact of the code we ported from the full .Net Framework. You can ignore them.&lt;/em&gt;&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;The vertical axis in the timeline view shows object addresses in the heap.&amp;#xA0; Given that the segments of the GC heap are not necessary contiguous you may seen gaps in these numbers.&amp;#xA0; If you'd like more information about the Compact Framework GC check out the following posts:&lt;/font&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;font size="2"&gt;&lt;a href="http://blogs.msdn.com/stevenpr/archive/2004/07/26/197254.aspx"&gt;An Overview of the .Net Compact Framework's Garbage Collector&lt;/a&gt;&lt;/font&gt;&lt;/li&gt;    &lt;li&gt;&lt;font size="2"&gt;&lt;a href="http://blogs.msdn.com/stevenpr/archive/2005/12/14/503818.aspx"&gt;GC Heap Management&lt;/a&gt;&lt;/font&gt;&lt;/li&gt;    &lt;li&gt;&lt;font size="2"&gt;&lt;a href="http://community.opennetcf.com/articles/cf/archive/2007/08/10/don-t-fear-the-garbage-collector.aspx"&gt;Don't Fear the Garbage Collector&lt;/a&gt;&lt;/font&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;h2&gt;Back to the Example&lt;/h2&gt;  &lt;p&gt;&lt;font size="2"&gt;Throughout this series of posts I've been using an example of a game I wrote that paints way too slowly.&amp;#xA0; In part 2 we saw that the vast majority of objects I'm creating are of type &lt;font face="Courier New"&gt;Box.Block&lt;/font&gt;.&amp;#xA0; Looking that the Timeline view confirms this as can be seen by looking at the legend and all the red in the view of the heap.&amp;#xA0; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;The time-based nature of this view allows us to get a few steps deeper into our analysis.&amp;#xA0; First, we can see the points in time at which allocations of our &lt;font face="Courier New"&gt;Blocks&lt;/font&gt; occurred.&amp;#xA0; In this case, that data isn't very interesting because the view tells me that I was almost continually allocating &lt;font face="Courier New"&gt;Blocks&lt;/font&gt;. &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;What's more important in my case is to discover which method in my application was doing the allocations at which point in time.&amp;#xA0; It may be that early on in my application my allocations were coming from &lt;font face="Courier New"&gt;MethodA&lt;/font&gt; while later on they were coming from &lt;font face="Courier New"&gt;MethodB&lt;/font&gt;.&amp;#xA0; This time-based analysis can be particularly useful if you'd like to see all that's happening when your application first starts, for example.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;To see where your allocations are coming from at a given point in time just select that time in the view.&amp;#xA0; This causes a vertical line to appear at that point in the graph.&amp;#xA0; Then right-click and select &amp;quot;Show Who Allocated&amp;quot; from the context menu:&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;img id="id" src="http://farm3.static.flickr.com/2149/2072014384_e3976a9ce6_o.jpg" /&gt; &lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;Doing so brings up the same Allocation Graph we looked at in part 2, except that the graph shows only the allocations done at that particular point in time.&amp;#xA0; In part 2 we saw that my allocations were coming from two methods: &lt;font face="Courier New"&gt;InitializeGameBlocks&lt;/font&gt; and &lt;font face="Courier New"&gt;RotateGameBlocks&lt;/font&gt;.&amp;#xA0; By using the timeline view I can see which of those methods was called at which times during my application.&amp;#xA0; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;Next time I'll describe the Call Tree view that will show even more detail by highlighting the exact lines within my methods that are causing the spurious allocations to occur.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;Thanks,&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;Steven&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;This posting is provided &amp;quot;AS IS&amp;quot; with no warranties, and confers no rights&lt;/p&gt;  &lt;p&gt;   &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=6583673" width="1" height="1"&gt;</content><author><name>stevenpr</name><uri>http://blogs.msdn.com/members/stevenpr.aspx</uri></author></entry><entry><title>Calling the EnumServices Win32 API from your .Net Compact Framework Application</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/stevenpr/archive/2007/11/20/calling-the-enumservices-win32-api-from-your-net-compact-framework-application.aspx" /><id>http://blogs.msdn.com/stevenpr/archive/2007/11/20/calling-the-enumservices-win32-api-from-your-net-compact-framework-application.aspx</id><published>2007-11-21T04:07:51Z</published><updated>2007-11-21T04:07:51Z</updated><content type="html">&lt;p&gt;&lt;font size="2"&gt;I was helping a customer use PInvoke to call &lt;font face="Courier New"&gt;EnumServices&lt;/font&gt; today and got stuck a few times so I thought it may be helpful to post the solution in case anyone else runs into this someday.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;&lt;font face="Courier New"&gt;EnumServices&lt;/font&gt; returns a buffer containing a number of structures of type &lt;font face="Courier New"&gt;ServiceEnumInfo&lt;/font&gt; that describe basic information about the services on a device.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;Each &lt;font face="Courier New"&gt;ServiceEnumInfo&lt;/font&gt; structure contains an embedded character array that represents the service's prefix and a pointer to a string that represents the name of the dll that implements the service.&amp;#xA0; The dll names corresponding to the structures are laid out in memory just after the structures themselves.&amp;#xA0; So the contents of the buffer you get back from calling &lt;font face="Courier "&gt;EnumServices&lt;/font&gt; looks like this (this example is from a device with 3 services):&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;&lt;img id="id" src="http://farm3.static.flickr.com/2156/2051602442_f2d9d48900_o.jpg" /&gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;Here's some sample code that calls &lt;font face="Courier New"&gt;EnumServices&lt;/font&gt; and loops the buffer pulling out both the prefix name and the dll name for each service:&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#004080"&gt;using System;     &lt;br /&gt;using System.Collections.Generic;      &lt;br /&gt;using System.ComponentModel;      &lt;br /&gt;using System.Data;      &lt;br /&gt;using System.Drawing;      &lt;br /&gt;using System.Text;      &lt;br /&gt;using System.Windows.Forms;      &lt;br /&gt;using System.Runtime.InteropServices;      &lt;br /&gt;using System.Diagnostics; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#004080"&gt;namespace EnumServices     &lt;br /&gt;{      &lt;br /&gt;&amp;#xA0;&amp;#xA0;&amp;#xA0; public partial class Form1 : Form      &lt;br /&gt;&amp;#xA0;&amp;#xA0;&amp;#xA0; {      &lt;br /&gt;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0; // Managed definition of the native ServiceEnumInfo structure.&amp;#xA0; Here's the corresponding native definition:      &lt;br /&gt;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0; //      &lt;br /&gt;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0; // typedef struct_ServiceEnumInfo {      &lt;br /&gt;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0; //&amp;#xA0;&amp;#xA0;&amp;#xA0; WCHAR szPrefix[6];      &lt;br /&gt;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0; //&amp;#xA0;&amp;#xA0;&amp;#xA0; WCHAR szDllName;      &lt;br /&gt;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0; //&amp;#xA0;&amp;#xA0;&amp;#xA0; HANDLE hServiceHandle;      &lt;br /&gt;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0; //&amp;#xA0;&amp;#xA0;&amp;#xA0; DWORD dwServiceState;      &lt;br /&gt;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0; // } ServiceEnumInfo;      &lt;br /&gt;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0; //      &lt;br /&gt;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0; struct ServiceEnumInfo      &lt;br /&gt;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0; {      &lt;br /&gt;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0; [MarshalAs(UnmanagedType.ByValTStr, SizeConst=6)] public String prefixName;      &lt;br /&gt;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0; public IntPtr pDllName; // this value is a pointer to the dll name - not the dll name itself.      &lt;br /&gt;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0; public IntPtr hServiceHandle;      &lt;br /&gt;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0; public int dwServiceState;      &lt;br /&gt;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0; } &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#004080"&gt;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0; [DllImport(&amp;quot;coredll.dll&amp;quot;)]     &lt;br /&gt;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0; private static extern int EnumServices(IntPtr pBuffer, ref int numEntries, ref int cbBuf); &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#004080"&gt;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0; public Form1()     &lt;br /&gt;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0; {      &lt;br /&gt;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0; InitializeComponent();      &lt;br /&gt;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0; } &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#004080"&gt;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0; private void btnServices_Click(object sender, EventArgs e)     &lt;br /&gt;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0; {      &lt;br /&gt;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0; int numEntries = 0;      &lt;br /&gt;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0; int cbSize = 0;      &lt;br /&gt;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0; int structSize = Marshal.SizeOf(typeof(ServiceEnumInfo)); &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#004080"&gt;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0; // call once to get required buffer size     &lt;br /&gt;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0; int result = EnumServices(IntPtr.Zero, ref numEntries, ref cbSize); &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#004080"&gt;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0; // alloc a buffer of the correct size     &lt;br /&gt;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0; IntPtr pBuffer = Marshal.AllocHGlobal(cbSize); &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#004080"&gt;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0; // call again to get the real stuff     &lt;br /&gt;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0; result = EnumServices(pBuffer, ref numEntries, ref cbSize); &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#004080"&gt;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0; // loop through the structure pulling out the prefix and the dll name     &lt;br /&gt;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0; for (int i = 0; i &amp;lt; numEntries; i++)      &lt;br /&gt;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0; {      &lt;br /&gt;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0; // move a pointer along to point to the &amp;quot;current&amp;quot; structure each time through the loop      &lt;br /&gt;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0; IntPtr pStruct = new IntPtr(pBuffer.ToInt32()+ (i * structSize)); &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#004080"&gt;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0; // &amp;quot;translate&amp;quot; the pointer into an actual structure     &lt;br /&gt;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0; ServiceEnumInfo sei = (ServiceEnumInfo)Marshal.PtrToStructure(pStruct, &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#004080"&gt;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0; typeof(ServiceEnumInfo)); &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#004080"&gt;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0; string prefix = sei.prefixName;     &lt;br /&gt;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0; string dllName = Marshal.PtrToStringUni(sei.pDllName); &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#004080"&gt;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0; // use the prefix and dllName as needed....     &lt;br /&gt;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0; Debug.WriteLine(prefix);      &lt;br /&gt;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0; Debug.WriteLine(dllName);      &lt;br /&gt;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0; } &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#004080"&gt;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0; // remember to free the buffer that we allocated     &lt;br /&gt;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0; Marshal.FreeHGlobal(pBuffer); &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#004080"&gt;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0;&amp;#xA0; }     &lt;br /&gt;&amp;#xA0;&amp;#xA0;&amp;#xA0; }      &lt;br /&gt;}&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#004080" size="2"&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;Thanks,&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;Steven&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;This posting is provided &amp;quot;AS IS&amp;quot; with no warranties, and confers no rights.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=6447873" width="1" height="1"&gt;</content><author><name>stevenpr</name><uri>http://blogs.msdn.com/members/stevenpr.aspx</uri></author></entry><entry><title>Great .Net Compact Framework Content at Oredev</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/stevenpr/archive/2007/11/09/great-net-compact-framework-content-at-oredev.aspx" /><id>http://blogs.msdn.com/stevenpr/archive/2007/11/09/great-net-compact-framework-content-at-oredev.aspx</id><published>2007-11-10T03:47:00Z</published><updated>2007-11-10T03:47:00Z</updated><content type="html">&lt;P&gt;&lt;FONT size=2&gt;Next week is the annual &lt;/FONT&gt;&lt;FONT size=2&gt;&lt;A href="http://www.oredev.org/" mce_href="http://www.oredev.org"&gt;Øredev&lt;/A&gt; &lt;/FONT&gt;conference in Malmö, Sweden.&amp;nbsp; We're very fortunate to have 3 detailed .Net Compact Framework sessions there.&amp;nbsp; Doug Boling will be doing sessions on &lt;A href="http://www.oredev.org/toppmeny/conference/embeddedsystem/compactframeworkperformance.4.76e8b1c6112f078db498000127374.html" mce_href="http://www.oredev.org/toppmeny/conference/embeddedsystem/compactframeworkperformance.4.76e8b1c6112f078db498000127374.html"&gt;performance&lt;/A&gt; and on how to &lt;A href="http://www.oredev.org/toppmeny/conference/embeddedsystem/towritegpsenabledapplications.4.76e8b1c6112f078db498000127345.html" mce_href="http://www.oredev.org/toppmeny/conference/embeddedsystem/towritegpsenabledapplications.4.76e8b1c6112f078db498000127345.html"&gt;enable GPS in your applications&lt;/A&gt; and I'll be doing a session on how to use the &lt;A href="http://www.oredev.org/toppmeny/conference/embeddedsystem/newandimproveddiagnostictools.4.76e8b1c6112f078db498000129363.html" mce_href="http://www.oredev.org/toppmeny/conference/embeddedsystem/newandimproveddiagnostictools.4.76e8b1c6112f078db498000129363.html"&gt;.Net Compact Framework diagnostic tools&lt;/A&gt; to solve tough issues like performance problems or memory leaks.&amp;nbsp; &lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;I'll also be presenting a session on &lt;A href="http://www.oredev.org/toppmeny/conference/net/silverlightindepth.4.76e8b1c6112f078db498000126618.html" mce_href="http://www.oredev.org/toppmeny/conference/net/silverlightindepth.4.76e8b1c6112f078db498000126618.html"&gt;Silverlight 1.1&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;If you're in that part of the world next week it's a great chance to get access to some .Net Compact Framework content.&amp;nbsp; Doug Boling knows a ton about WindowsCE and is a great resource.&lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;Thanks,&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;Steven&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;This posting is provided "AS IS" with no warranties, and confers no rights.&lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=6034039" width="1" height="1"&gt;</content><author><name>stevenpr</name><uri>http://blogs.msdn.com/members/stevenpr.aspx</uri></author></entry><entry><title>What's new in the Remote Performance Monitor for .Net Compact Framework 3.5</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/stevenpr/archive/2007/10/26/what-s-new-in-the-remote-performance-monitor-for-net-compact-framework-3-5.aspx" /><id>http://blogs.msdn.com/stevenpr/archive/2007/10/26/what-s-new-in-the-remote-performance-monitor-for-net-compact-framework-3-5.aspx</id><published>2007-10-27T03:40:18Z</published><updated>2007-10-27T03:40:18Z</updated><content type="html">&lt;p&gt;&lt;font size="2"&gt;The &lt;a href="http://blogs.msdn.com/stevenpr/archive/2006/04/17/577636.aspx"&gt;Remote Performance Monitor (RPM)&lt;/a&gt; first shipped in version 2 service pack 1 of the .Net Compact Framework.&amp;#xA0; Since that time, numerous customers have come to depend on RPM to help them diagnose performance problems and find memory leaks in their applications.&amp;#xA0; With each release we add new features and fix bugs based on what customers tell us is important, and version 3.5 is no exception.&amp;#xA0; This post summarizes what's new in v3.5.&amp;#xA0; &lt;/font&gt;&lt;/p&gt;  &lt;h1&gt;Emulator support&lt;/h1&gt;  &lt;p&gt;&lt;font size="2"&gt;One of the most glaring omissions from RPM in previous releases was the lack of support for emulators.&amp;#xA0; Thankfully, in version 3.5 you can use the WindowsMobile and WindowsCE emulators with RPM just as you would a &amp;quot;real&amp;quot; device.&lt;/font&gt;&lt;/p&gt;  &lt;h1&gt;Auto-deployment of device-side components&lt;/h1&gt;  &lt;p&gt;&lt;font size="2"&gt;The 3.5 version of RPM no longer requires any manual setup steps.&amp;#xA0; Previously, you had to manually copy &lt;font face="Courier New"&gt;netcfrtl.dll&lt;/font&gt; and the VSD transports to your device before using RPM.&amp;#xA0; Now, RPM does everything for you: if anything RPM depends on is missing from your device, those dependencies will be copied before you launch an application.&lt;/font&gt;&lt;/p&gt;  &lt;h1&gt;New User Interface&lt;/h1&gt;  &lt;p&gt;&lt;font size="2"&gt;RPM's user interface has been streamlined to make the process of collecting and browsing performance statistics and analyzing GC heap dumps easier.&amp;#xA0; We've removed the use of MDI to manage windows, simplified the menu options and added a dialog used to launch applications.&amp;#xA0; Here's a screenshot of a section of the new UI.&amp;#xA0; None of us are UI gurus here on the .Net Compact Framework team, but we hope our new approach is an improvement.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;img id="id" src="http://farm3.static.flickr.com/2083/1765778587_379f64c9d6.jpg" /&gt; &lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;We also keep track of the applications you've previously launched so you don't have to retype them every time.&amp;#xA0; I always hated that....&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;  &lt;h1&gt;Improved Device Management&lt;/h1&gt;  &lt;p&gt;&lt;font size="2"&gt;RPM now includes a new component that lets you manage the devices you'd like to connect to.&amp;#xA0; The following device management form can be accessed from the Browse button on the launch dialog (see the previous picture):&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;&lt;img id="id" src="http://farm3.static.flickr.com/2141/1765778441_5670955012.jpg" /&gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;This dialog makes it much easier for you to work with your devices.&amp;#xA0; As with previous releases, RPM knows about Active Sync devices automatically.&amp;#xA0; You can now add and save devices connected over tcp/ip so you don't have to retype the addresses each time you'd like to use the device.&amp;#xA0; You can also set various device properties and designate one of your devices as the default device.&amp;#xA0; Tagging a device as the default causes it to be automatically selected when the launch dialog is displayed.&lt;/font&gt;&lt;/p&gt;  &lt;h1&gt;Remote Installation of .Net CF&lt;/h1&gt;  &lt;p&gt;&lt;font size="2"&gt;Installing .Net CF into RAM typically involves either rerunning the SDK setup program or browsing through your file system searching for the correct cab to install, manually copying it to the device and launching the cab installer. With RPM 3.5 you can install Net CF onto your device using the device management dialog as shown below:&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;img id="id" src="http://farm3.static.flickr.com/2134/1765829657_759ad6ee77_o.jpg" /&gt; &lt;/p&gt;  &lt;h1&gt;&amp;#xA0;&lt;/h1&gt;  &lt;h1&gt;&amp;#xA0;&lt;/h1&gt;  &lt;p&gt;&lt;font size="2"&gt;RPM will detect the version of the OS on the device, along with the processor type, and deploy the correct cab file.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;  &lt;h1&gt;Deployment of your application from RPM&lt;/h1&gt;  &lt;p&gt;&lt;font size="2"&gt;If the application you'd like to launch isn't present on your device, you can now use RPM to deploy it.&amp;#xA0; On the launch dialog you'll see two fields: &amp;quot;&lt;/font&gt;&lt;font size="2"&gt;&lt;em&gt;Deploy application from&lt;/em&gt;&amp;quot; and &amp;quot;&lt;em&gt;Application&lt;/em&gt;&amp;quot;:&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;img id="id" src="http://farm3.static.flickr.com/2083/1765778587_379f64c9d6.jpg" /&gt; &lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;As you'd expect, &amp;quot;&lt;em&gt;Deploy application from&lt;/em&gt;&amp;quot; is the location on your desktop computer where the .Net Compact Framework application executable you'd like to deploy resides.&amp;#xA0; The &amp;quot;&lt;em&gt;Application&lt;/em&gt;&amp;quot; field is the location on the device you'd like your application deployed to.&amp;#xA0; There is one subtlety in the use of these fields to remember: in the &amp;quot;&lt;em&gt;Deploy application from&lt;/em&gt;&amp;quot; field you specify the directory your application resides in, not including the name of the executable itself.&amp;#xA0; In the &amp;quot;&lt;em&gt;Application&lt;/em&gt;&amp;quot; field you specify the fully qualified name of the destination on device, including executable name.&amp;#xA0; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;For example, say I'd like RPM to deploy the file stored on my desktop computer at &lt;font face="Courier New"&gt;c:\temp\neilyoung\archives\riverboat.exe&lt;/font&gt; to the &lt;font face="Courier New"&gt;\program files\sjp&lt;/font&gt; directory on my device.&amp;#xA0; The values of the two fields would be:&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;&lt;img id="id" src="http://farm3.static.flickr.com/2003/1766175967_ae6af26138_o.jpg" /&gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&amp;#xA0;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;This feature can only be used to deploy applications consisting of a single file.&amp;#xA0; If your application contains one executable file and several dlls you'll still have to deploy your application manually.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;We hope these improvements make RPM an even better tool.&amp;#xA0; As always, please keep the feedback coming.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;Thanks,&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;Steven&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;This posting is provided &amp;quot;AS IS&amp;quot; with no warranties, and confers no rights.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=5697670" width="1" height="1"&gt;</content><author><name>stevenpr</name><uri>http://blogs.msdn.com/members/stevenpr.aspx</uri></author></entry><entry><title>The CLRProfiler for the .Net Compact Framework, Part II: Histograms and "Show who Allocated"</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/stevenpr/archive/2007/10/18/the-clrprofiler-for-the-net-compact-framework-part-ii-histograms-and-show-who-allocated.aspx" /><id>http://blogs.msdn.com/stevenpr/archive/2007/10/18/the-clrprofiler-for-the-net-compact-framework-part-ii-histograms-and-show-who-allocated.aspx</id><published>2007-10-18T20:22:31Z</published><updated>2007-10-18T20:22:31Z</updated><content type="html">&lt;p&gt;&lt;font size="2"&gt;Yesterday I started a series of posts on how the use the CLRProfiler for the .Net Compact Framework.&amp;#xA0; The &lt;a href="http://blogs.msdn.com/stevenpr/archive/2007/10/17/the-clrprofiler-for-the-net-compact-framework-part-1-getting-started.aspx"&gt;first post&lt;/a&gt; contained the basic information you need to get started.&amp;#xA0; I described how to install the profiler, launch an application on the device, and collect profiling data.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;In order to direct the discussion, I've written a sample application that exhibits a performance problem that is surprisingly easy to fall into.&amp;#xA0; Throughout these posts I'll show you how to use the profiler to diagnose the problem.&amp;#xA0; To refresh your memory, the sample application is a basic game and the performance problem is that the main windows paints way too slowly.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;After I stopped profiling the game in the first post, following summary page was displayed.&amp;#xA0; &lt;/font&gt;&amp;#xA0;&lt;img id="id" src="http://farm3.static.flickr.com/2366/1607249692_781068c831.jpg" /&gt; &lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;&lt;font size="2"&gt;In this post I'll use some of the histograms to begin diagnosing our performance problem.&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;  &lt;h1&gt;Histograms&lt;/h1&gt;  &lt;p&gt;&lt;font size="2"&gt;The first thing that stands out at me when looking at the summary form is the amount of managed data I'm creating.&amp;#xA0; While profiling the painting portion of my application I generated over 6MB of managed objects.&amp;#xA0; That's clearly way too much for a relatively simple operation like painting my main window.&amp;#xA0; My first step in determining what's going on is to get some basic statistics about the objects my application is using.&amp;#xA0; For example, I'm interested in which objects I'm creating, how many of them there are and how long they live.&amp;#xA0; This data can be obtained by looking at some of the histograms the profiler offers.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;I can choose to view a histogram for all objects created as my application ran or only for those objects that were in the GC heap when my application exited.&amp;#xA0; In my scenario I need to look at all objects.&amp;#xA0; If I were to only look at the objects alive at the end of the run I may miss some important trend that occurred earlier on.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;Clicking the &amp;quot;&lt;em&gt;Histogram&lt;/em&gt;&amp;quot; button next to the &amp;quot;&lt;em&gt;Allocated Bytes&lt;/em&gt;&amp;quot; value displays the following graph:&lt;/font&gt;&amp;#xA0;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt; &lt;font size="2"&gt;&lt;img id="id" src="http://farm3.static.flickr.com/2116/1618435871_825a99788d.jpg" /&gt; &lt;/font&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;The histogram form has two panes. The pane on the right describes how many instances of each type of object were created and the total size of those instances.&amp;#xA0; The pane on the left graphs type instances by size.&amp;#xA0; The color coding next to the types in the right pane matches the bars in the left pane which show the relative amounts of objects created.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;A quick glance at this form helps narrow my suspicions about what's causing my performance issue.&amp;#xA0; As you can see, about 97% of the objects I created were of type &lt;font face="Courier New"&gt;Box.Block&lt;/font&gt; as indicated by the red box on the right hand pane and the red bar in the left hand pane.&amp;#xA0; I can also see that each instance of &lt;font face="Courier New"&gt;Box.Block&lt;/font&gt; is relatively small at an average size of 136 bytes (see the right hand pane).&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&amp;#xA0;&lt;/p&gt;  &lt;h1&gt;Who Allocated all those Objects?&lt;/h1&gt;  &lt;p&gt;&lt;font size="2"&gt;Now that I know the majority of my objects are instances of &lt;font face="Courier New"&gt;Box.Block&lt;/font&gt;, I'd like to see where in my application those instances are getting created.&amp;#xA0; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;To determine the source of my allocations I can right-click on the bar that represents &lt;font face="Courier New"&gt;Box.Block&lt;/font&gt; in the histogram and select &amp;quot;&lt;em&gt;Show Who Allocated&lt;/em&gt;&amp;quot; (the bar turns black when selected):&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;img id="id" src="http://farm3.static.flickr.com/2034/1621134688_0a16602c4b.jpg" /&gt; &lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;Doing so brings up a window referred to as an Allocation Graph:&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;&lt;img id="id" src="http://farm3.static.flickr.com/2279/1619717659_ec0f0d62b3.jpg" /&gt; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;The Allocation Graph traces the flow of every call that allocated an instance of &lt;font face="Courier New"&gt;Box.Block&lt;/font&gt;.&amp;#xA0; I typically interpret this graph starting with the rightmost node.&amp;#xA0; This node represents all instances of &lt;font face="Courier New"&gt;Box.Block&lt;/font&gt; in the system.&amp;#xA0; Stepping back one level to the left we see two nodes representing methods that created instances of &lt;font face="Courier New"&gt;Box.Block&lt;/font&gt;: &lt;font face="Courier New"&gt;Form1.RotateGameBlocks&lt;/font&gt; and &lt;font face="Courier New"&gt;Form1.InitializeGameBlocks&lt;/font&gt;. The data in these nodes tell us that 75% of the &lt;font face="Courier New"&gt;Block&lt;/font&gt;s were created in &lt;font face="Courier New"&gt;RotateGameBlocks&lt;/font&gt; and 25% were created in &lt;font face="Courier New"&gt;InitializeGameBlocks&lt;/font&gt;.&amp;#xA0; Notice that the width of the lines connecting the nodes represents the percentage of instances that call created.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;Now that I know where my objects are coming from I can dig into my code to see what's going on.&amp;#xA0; &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;In some scenarios, the information we've learned so far may be all that we need to fix the problem.&amp;#xA0; However, there are a few more pieces of data that may be required in some cases.&amp;#xA0; For example, it may be useful to know the times at which &lt;font face="Courier New"&gt;Blocks&lt;/font&gt; were created and destroyed.&amp;#xA0; Also, if &lt;font face="Courier New"&gt;RotateGameBlocks&lt;/font&gt; and &lt;font face="Courier New"&gt;InitializeGameBlocks&lt;/font&gt; are long, complicated methods, we may need to know the exact calls within those methods that caused the allocations.&amp;#xA0; I'll describe how to get this information in future posts.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;Thanks,&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;Steven&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;This posting is provided &amp;quot;AS IS&amp;quot; with no warranties, and confers no rights&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=5514436" width="1" height="1"&gt;</content><author><name>stevenpr</name><uri>http://blogs.msdn.com/members/stevenpr.aspx</uri></author><category term="Diagnostics" scheme="http://blogs.msdn.com/stevenpr/archive/tags/Diagnostics/default.aspx" /></entry><entry><title>The CLRProfiler for the .Net Compact Framework, Part 1: Getting Started</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/stevenpr/archive/2007/10/17/the-clrprofiler-for-the-net-compact-framework-part-1-getting-started.aspx" /><id>http://blogs.msdn.com/stevenpr/archive/2007/10/17/the-clrprofiler-for-the-net-compact-framework-part-1-getting-started.aspx</id><published>2007-10-18T04:28:00Z</published><updated>2007-10-18T04:28:00Z</updated><content type="html">&amp;nbsp;&lt;A href="http://msdn2.microsoft.com/en-us/vstudio/aa700831.aspx" mce_href="http://msdn2.microsoft.com/en-us/vstudio/aa700831.aspx"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"&gt;Version 3.5 of the .Net Compact Framework&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"&gt; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"&gt;contains a new memory profiler called the CLRProfiler.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;The CLRProfiler is a great tool for looking into the details of how your application is allocating and using managed objects.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;For example, the profiler allows you to look at the contents of the GC heap at any point in time, provides a historical record of what's going on in the heap, let's you see which calls in your application are allocating which objects and so on.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;This level of detail is often needed to diagnose memory-related issues in your device applications.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;The Compact Framework's version of the CLRProfiler is an adaptation of the profiler that has been available for the full .Net Framework for some time.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana" mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana"&gt;In this series of posts I'll walk you through the primary features of the CLRProfiler for the .Net Compact Framework.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;The profiler contains numerous ways to analyze data about the GC heap so instead of briefly touching on all of them, I'll go into depth on the views I've found most useful.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana" mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana"&gt;We'll be looking at the profiler by way of an example, as I've found that learning a new tool is often easier if you have a specific problem to solve rather than just looking at the tool's features without any context.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;If you'd like more information on a view that I don't cover here you can read the &lt;A href="http://www.microsoft.com/downloads/details.aspx?FamilyID=a362781c-3870-43be-8926-862b40aa0cd0&amp;amp;DisplayLang=en" mce_href="http://www.microsoft.com/downloads/details.aspx?FamilyID=a362781c-3870-43be-8926-862b40aa0cd0&amp;amp;DisplayLang=en"&gt;document that ships with the full Framework's version of the profiler&lt;/A&gt;.&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana" mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="FONT-SIZE: 12pt; MARGIN: 0in; FONT-FAMILY: Verdana"&gt;&lt;STRONG&gt;Our Sample&lt;/STRONG&gt;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana" mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana"&gt;The sample I'll use to describe the profiler is the beginnings of a game I started to write using the Compact Framework.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;All the game currently does is allow you to start a new game and to rotate a set of blocks on the screen.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Here's a simple view of the application:&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana" mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;&lt;A title="Photo Sharing" href="http://www.flickr.com/photos/stevenjpr/1605122889/"&gt;&lt;IMG height=559 alt=prof1 src="http://farm3.static.flickr.com/2364/1605122889_08f14f38c7_o.jpg" width=371&gt;&lt;/A&gt; 
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana" mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;&lt;FONT face=Verdana&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana"&gt;The performance problem I'm having with this game involves my drawing logic.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;The blocks on the screen draw very slowing.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;On my Dell Axim I can literally see each column of blocks paint individually.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Throughout these posts I'll use the CLRProfiler to figure out what I can do to make my game paint more quickly.&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana" mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="FONT-SIZE: 12pt; MARGIN: 0in; FONT-FAMILY: Verdana"&gt;&lt;STRONG&gt;Launching an Application with the CLRProfiler&lt;/STRONG&gt;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana" mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana" mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana"&gt;The CLRProfiler ships in the &lt;A href="http://www.microsoft.com/downloads/details.aspx?familyid=C8174C14-A27D-4148-BF01-86C2E0953EAB&amp;amp;displaylang=en"&gt;.Net Compact Framework Power Toys&lt;/A&gt; package.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;After installing the Power Toys you can find the CLRProfiler executable (NetCFClrProfiler.exe) in the bin directory of the .Net SDK.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;On my machine that directory is c:\Program Files\Microsoft.Net\SDK\CompactFramework\v3.5\bin.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;The Power Toys setup program also adds a menu item for the profiler to the Windows Start menu.&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana" mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana"&gt;The main window of the profiler is strikingly simple:&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana" mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;&lt;A title="Photo Sharing" href="http://www.flickr.com/photos/stevenjpr/1606427830/"&gt;&lt;IMG height=171 alt=prof2 src="http://farm3.static.flickr.com/2271/1606427830_e2a1bdfc80_o.jpg" width=327&gt;&lt;/A&gt; 
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana" mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana" mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana"&gt;Through this main window you can start and stop applications, take snapshots of the GC heap, and control various profiling options.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;These options include control over whether profiling is currently active and whether allocations, calls or both are logged.&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana" mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana"&gt;Clicking the "&lt;EM&gt;Start Application&lt;/EM&gt;…" button displays the following form:&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana" mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;&lt;A title="Photo Sharing" href="http://www.flickr.com/photos/stevenjpr/1607249510/"&gt;&lt;IMG height=213 alt=prof3 src="http://farm3.static.flickr.com/2021/1607249510_6d7c969551_o.jpg" width=641&gt;&lt;/A&gt; 
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana" mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;&lt;/FONT&gt;&lt;FONT face=Verdana&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana"&gt;On this form you enter the name of the device you'd like to connect to, the fully qualified path to the device executable you'd like to profile, and any command line parameters to be passed to the application.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;The CLRProfiler supports profiling applications on devices connected either over ActiveSync or TCP/IP.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;You can also profile applications running on emulators.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;The profiler supports the same types of devices that&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;the &lt;A href="http://blogs.msdn.com/stevenpr/archive/2006/04/17/577636.aspx"&gt;.Net Compact Framework Performance Monitor&lt;/A&gt; does(in fact, the device selection and connectivity mechanisms are shared between the two tools).&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana" mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in"&gt;&lt;SPAN style="FONT-FAMILY: Verdana"&gt;In my example I have a device connected over ActiveSync and the name of my application is &lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 'Courier New'"&gt;box.exe&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: Verdana"&gt;.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Selecting "&lt;EM&gt;Connect&lt;/EM&gt;" from the launch dialog starts the application on device and begins profiling.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;At this point just run your application as you normally would.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;The CLRProfiler causes your application to run much slower than normal.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;In order to speed up the debugging process you can turn profiling on and off for different sections of your application using the "&lt;EM&gt;Profiling active&lt;/EM&gt;" checkbox on the profiler's main form.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana" mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana"&gt;When you're done profiling your application, you can stop it either by selecting the "&lt;EM&gt;Kill Application&lt;/EM&gt;" button on the main form of the CLRProfiler or by just closing the application directly on the device.&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana" mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="FONT-SIZE: 12pt; MARGIN: 0in; FONT-FAMILY: Verdana"&gt;&lt;STRONG&gt;The Summary Form&lt;/STRONG&gt;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana" mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana"&gt;After your application exits the CLRProfiler displays the following summary form:&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana" mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;&lt;A title="Photo Sharing" href="http://www.flickr.com/photos/stevenjpr/1607249692/"&gt;&lt;IMG height=263 alt=prof4 src="http://farm3.static.flickr.com/2366/1607249692_781068c831.jpg" width=500&gt;&lt;/A&gt; 
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana" mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;&lt;/FONT&gt;&lt;FONT face=Verdana&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana"&gt;The summary form provides some general statistics about the use of managed memory as your application ran:&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana" mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;UL style="MARGIN-TOP: 0in; MARGIN-BOTTOM: 0in; MARGIN-LEFT: 0.75in; DIRECTION: ltr; unicode-bidi: embed" type=circle&gt;
&lt;LI style="MARGIN-TOP: 0px; MARGIN-BOTTOM: 0px; VERTICAL-ALIGN: middle"&gt;&lt;SPAN style="FONT-WEIGHT: bold; FONT-SIZE: 10pt; FONT-FAMILY: Verdana"&gt;Heap Statistics.&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"&gt; The statistics displayed in this group box describe the total size of the objects in the managed heap.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;The "&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-STYLE: italic; FONT-FAMILY: Verdana"&gt;Allocated Bytes"&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"&gt; value counts the total size of allocations made as the application was running.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;When the Compact Framework garbage collector detects significant fragmentation in the heap, it will compact it.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;The "&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-STYLE: italic; FONT-FAMILY: Verdana"&gt;Relocated Bytes&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"&gt;" value shows how many bytes the garbage collector moved around during compaction.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;"&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-STYLE: italic; FONT-FAMILY: Verdana"&gt;Final Heap Bytes&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"&gt;" shows the size of the managed heap when the application exited and "&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-STYLE: italic; FONT-FAMILY: Verdana"&gt;Objects Finalized&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"&gt;" is what you'd expect: the number of objects that had finalizers to run.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Note that the Heap Statistics group also provides a count of critical finalizers run.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;The .Net Compact Framework doesn't have the notion of critical finalization so this value will always be 0.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in 0in 0in 0.75in; FONT-FAMILY: Verdana" mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in 0in 0in 0.75in; FONT-FAMILY: Verdana"&gt;There are several buttons in this box that launch viewers that allow you to analyze data in various ways.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;You can view data in histograms based on object size, age, address and so on.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;I'll describe most of these views in detail in subsequent posts.&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in 0in 0in 0.75in; FONT-FAMILY: Verdana" mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;UL style="MARGIN-TOP: 0in; MARGIN-BOTTOM: 0in; MARGIN-LEFT: 0.75in; DIRECTION: ltr; unicode-bidi: embed" type=circle&gt;
&lt;LI style="MARGIN-TOP: 0px; MARGIN-BOTTOM: 0px; VERTICAL-ALIGN: middle"&gt;&lt;SPAN style="FONT-WEIGHT: bold; FONT-SIZE: 10pt; FONT-FAMILY: Verdana"&gt;Garbage Collection Statistics.&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"&gt; This group box tells you how many garbage collections occurred while your application was being profiled and how many of those collections were induced by calls to &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;GC.Collect&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"&gt;.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;The "&lt;EM&gt;Timeline&lt;/EM&gt;" button enables you to see how the contents of the GC heap changes over time.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;I think this is one of the coolest views.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;I'll describe it in great detail in a subsequent post.&lt;/SPAN&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in 0in 0in 0.75in; FONT-FAMILY: Verdana" mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;UL style="MARGIN-TOP: 0in; MARGIN-BOTTOM: 0in; MARGIN-LEFT: 0.75in; DIRECTION: ltr; unicode-bidi: embed" type=circle&gt;
&lt;LI style="MARGIN-TOP: 0px; MARGIN-BOTTOM: 0px; VERTICAL-ALIGN: middle"&gt;&lt;SPAN style="FONT-WEIGHT: bold; FONT-SIZE: 10pt; FONT-FAMILY: Verdana"&gt;GC Handle Statistics.&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"&gt; The GC Handles group box shows you how many handles were created and destroyed while your application ran.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Keep in mind that the Compact Framework CLR creates GCHandles under the covers as it executes your application so all of the handles you see here aren't likely to have been created explicitly by you.&lt;/SPAN&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in 0in 0in 0.75in; FONT-FAMILY: Verdana" mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;UL style="MARGIN-TOP: 0in; MARGIN-BOTTOM: 0in; MARGIN-LEFT: 0.75in; DIRECTION: ltr; unicode-bidi: embed" type=circle&gt;
&lt;LI style="MARGIN-TOP: 0px; MARGIN-BOTTOM: 0px; VERTICAL-ALIGN: middle"&gt;&lt;SPAN style="FONT-WEIGHT: bold; FONT-SIZE: 10pt; FONT-FAMILY: Verdana"&gt;Profiling Statistics.&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"&gt; The CLRProfiler enables you to take snapshots of the GC heap as your application is running.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;I didn't do this while profiling my application, but if I would have I would be able to choose a snapshot from the dropdown and view it.&lt;/SPAN&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana" mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana"&gt;Getting back to our example, there are several pieces of data on this form that concern me, or are unexpected.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;The key to analyzing performance data such as this is not just looking at the raw values, but in interpreting the values in the context of what your application was doing as it was being profiled.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;For example, I profiled the time my application spent painting, yet I see that 5 garbage collections occurred and I created over 6 MB worth of objects.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;This data leads me to believe that I'm making the garbage collector work harder than it should for my scenario.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Clearly there shouldn't be so much activity going on in the managed heap while I'm painting boxes on the screen!&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana" mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana"&gt;In my next post, we'll use some of the histogram views to see how many objects my application is creating and of what type they are.&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana" mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana"&gt;Thanks,&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana"&gt;Steven&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana" mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: Verdana"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: 'Rockwell','serif'; mso-ansi-language: EN"&gt;This posting is provided "AS IS" with no warranties, and confers no rights.&lt;/SPAN&gt;&lt;/P&gt;&lt;/FONT&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=5502740" width="1" height="1"&gt;</content><author><name>stevenpr</name><uri>http://blogs.msdn.com/members/stevenpr.aspx</uri></author><category term="Diagnostics" scheme="http://blogs.msdn.com/stevenpr/archive/tags/Diagnostics/default.aspx" /></entry><entry><title>Write your own GC Heap Viewer for the .Net Compact Framework</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/stevenpr/archive/2007/09/21/write-your-own-gc-heap-viewer-for-the-net-compact-framework.aspx" /><id>http://blogs.msdn.com/stevenpr/archive/2007/09/21/write-your-own-gc-heap-viewer-for-the-net-compact-framework.aspx</id><published>2007-09-21T19:52:00Z</published><updated>2007-09-21T19:52:00Z</updated><content type="html">The last few versions of the &lt;a class="" href="http://blogs.msdn.com/stevenpr/archive/2006/04/17/577636.aspx" mce_href="http://blogs.msdn.com/stevenpr/archive/2006/04/17/577636.aspx"&gt;Remote Performance Monitor&lt;/a&gt; enable you to &lt;a class="" href="http://blogs.msdn.com/stevenpr/archive/2007/03/08/finding-managed-memory-leaks-using-the-net-cf-remote-performance-monitor.aspx" mce_href="http://blogs.msdn.com/stevenpr/archive/2007/03/08/finding-managed-memory-leaks-using-the-net-cf-remote-performance-monitor.aspx"&gt;view snapshots of the GC heap on demand&lt;/a&gt;.&amp;#xA0; The view of the heap presented by RPM is oriented around finding managed memory leaks.&amp;#xA0; Specifically, the data is organized so that it's easy to see which GC root is responsible for keeping a given object instance alive.&amp;#xA0; &lt;p&gt;We hope the views are well organized and easy to understand, but if you find they don't suite your needs for any reason you can write your own tool to analyze and display the heap data.&amp;#xA0; For example, maybe you want a fancier graphical representation, or you want a view tailored to a scenario other than finding memory leaks. &lt;/p&gt;  &lt;p&gt;You can't currently plug your new UI directly into RPM but you can save the heap snapshots to a file and create your own tool to view the data.&lt;/p&gt;  &lt;p&gt;In this post I'll briefly describe how to save the heap data then I'll provide the details of the file format.&lt;/p&gt;  &lt;h3&gt;Saving a GC Log&lt;/h3&gt;  &lt;p&gt;Saving a snapshot of the GC heap to a file is easy: Given an open view, just select the &amp;quot;Save&amp;quot; option from the &amp;quot;File&amp;quot; menu:&lt;/p&gt; &lt;a title="Photo Sharing" href="http://www.flickr.com/photos/stevenjpr/1418622344/" mce_href="http://www.flickr.com/photos/stevenjpr/1418622344/"&gt;&lt;img height="440" alt="save" src="http://farm2.static.flickr.com/1074/1418622344_a480d5104e_o.jpg" width="662" mce_src="http://farm2.static.flickr.com/1074/1418622344_a480d5104e_o.jpg" /&gt;&lt;/a&gt;   &lt;p&gt;You'll also be prompted to save any unsaved views when you close them.&lt;/p&gt;  &lt;h3&gt;The GC Log File Format&lt;/h3&gt;  &lt;p&gt;GC heap dump files are text files that include information for every object present in the GC heap at the time the heap dump was generated using RPM.&amp;#xA0; &lt;/p&gt;  &lt;p&gt;Each line in the text file contains one record.&amp;#xA0; There are 5 different types of records:&lt;/p&gt;  &lt;ul type="disc"&gt;   &lt;li&gt;&lt;b&gt;AppDomain record.&lt;/b&gt; Identifies the application domain for which a dump file applies. &lt;/li&gt;    &lt;li&gt;&lt;b&gt;Type record.&lt;/b&gt; Describes a type present in the heap. &lt;/li&gt;    &lt;li&gt;&lt;b&gt;Object record.&lt;/b&gt; Describes an instance of a type present in the heap. &lt;/li&gt;    &lt;li&gt;&lt;b&gt;Root record.&lt;/b&gt; Describes a root instance. &lt;/li&gt;    &lt;li&gt;&lt;b&gt;End AppDomain record.&lt;/b&gt; Marks the end of the dump file.&lt;/li&gt; &lt;/ul&gt;  &lt;p mce_keep="true"&gt;&amp;#xA0;&lt;/p&gt;  &lt;p&gt;Each record contains a number of elements separated by spaces.&amp;#xA0; The first element in each line indicates the record type.&amp;#xA0; Here's a portion of a dump file:&lt;/p&gt;  &lt;p&gt;&lt;b&gt;Note&lt;/b&gt;: This example is intended to show format only - it's likely not semantically accurate.&lt;/p&gt;  &lt;p&gt;a 2 bubblecs.exe&lt;/p&gt;  &lt;p&gt;t 2 System.RuntimeType&lt;/p&gt;  &lt;p&gt;o 7c79f 2 64&lt;/p&gt;  &lt;p&gt;t 1 System.NullReferenceException&lt;/p&gt;  &lt;p&gt;o 7cb42 2 64&lt;/p&gt;  &lt;p&gt;o 1ce004 1 18&lt;/p&gt;  &lt;p&gt;t 3 System.OutOfMemoryException&lt;/p&gt;  &lt;p&gt;o 1ce056 1d 118 1ce11f 1ce14c 1ce079 1ce113 1ce116 1ce267 1ce26a 1ce26d&lt;/p&gt;  &lt;p&gt;r 22c81b 5 0&lt;/p&gt;  &lt;p&gt;o 22c81e 1b 24&lt;/p&gt;  &lt;p&gt;r 22c81e 5 0&lt;/p&gt;  &lt;p&gt;o 22c823 1b 28&lt;/p&gt;  &lt;p&gt;r 22c823 5 0&lt;/p&gt;  &lt;p&gt;c bubblecs.exe&lt;/p&gt;  &lt;p mce_keep="true"&gt;&amp;#xA0;&lt;/p&gt;  &lt;h4&gt;AppDomain Record&lt;/h4&gt;  &lt;p&gt;An AppDomain record initiates a section of the file pertaining to a particular application domain.&amp;#xA0; Within that section is all the type, object and root information for the managed objects in that application domain.&amp;#xA0; All AppDomain records are closed with a corresponding End AppDomain record.&lt;/p&gt;  &lt;p&gt;The AppDomain record has 4 elements: &lt;/p&gt;  &lt;ul type="disc"&gt;   &lt;li&gt;&lt;b&gt;The letter &amp;quot;a&amp;quot;.&lt;/b&gt; Identifies the record as an application record. &lt;/li&gt;    &lt;li&gt;&lt;b&gt;Version number.&lt;/b&gt; A number used to track the file format of the dump file itself.&amp;#xA0; In the current releases this number will always be &amp;quot;2&amp;quot;. &lt;/li&gt;    &lt;li&gt;&lt;b&gt;AppDomain Name.&lt;/b&gt; The name of the application domain from which this dump file was generated.&amp;#xA0; This is typically the name of the exe that was run in the app domain. &lt;/li&gt;    &lt;li&gt;&lt;b&gt;Timestamp.&lt;/b&gt; The time at which the heap dump was take.&amp;#xA0; RPM obtains this number by calling the WinCE API GetTickCount.&lt;/li&gt; &lt;/ul&gt;  &lt;p mce_keep="true"&gt;&amp;#xA0;&lt;/p&gt;  &lt;p&gt;Example:&lt;/p&gt;  &lt;p&gt;a 2 NHLSchedule.exe 444d20df&lt;/p&gt;  &lt;p mce_keep="true"&gt;&amp;#xA0;&lt;/p&gt;  &lt;h4&gt;Type Record&lt;/h4&gt;  &lt;p&gt;Type records identify types in the GC heap.&amp;#xA0; Each type record contains 3 elements:&lt;/p&gt;  &lt;ul type="disc"&gt;   &lt;li&gt;&lt;b&gt;The letter &amp;quot;t&amp;quot;.&lt;/b&gt; Identifies the record as a type record. &lt;/li&gt;    &lt;li&gt;&lt;b&gt;Type ID.&lt;/b&gt; A unique numerical identifier for this type.&amp;#xA0; This identifier is used to tie object instances to their types (see description of Object Records below). &lt;/li&gt;    &lt;li&gt;&lt;b&gt;Type name.&lt;/b&gt;&amp;#xA0; The fully qualified name of the type.&lt;/li&gt; &lt;/ul&gt;  &lt;p mce_keep="true"&gt;&amp;#xA0;&lt;/p&gt;  &lt;p&gt;Example:&lt;/p&gt;  &lt;p&gt;t a1 Western.Pacific.SanJoseSharks&lt;/p&gt;  &lt;p&gt;Note:&lt;/p&gt;  &lt;ul type="disc"&gt;   &lt;li&gt;Type identifiers are not guaranteed to be unique across dump files.&amp;#xA0; For example, the identifier for the &amp;quot;SanJoseSharks&amp;quot; type in the example above isn't guaranteed to be a1 in a different dump taken from the same application at a different point in time.&lt;/li&gt; &lt;/ul&gt;  &lt;h4&gt;Object Record&lt;/h4&gt;  &lt;p&gt;Object records describe specific instances of types in the GC heap.&amp;#xA0; Object records have a variable number of elements.&amp;#xA0; The first 4 elements are required:&lt;/p&gt;  &lt;ul type="disc"&gt;   &lt;li&gt;&lt;b&gt;The letter &amp;quot;o&amp;quot;.&lt;/b&gt; Identifies the record as an object record. &lt;/li&gt;    &lt;li&gt;&lt;b&gt;Object ID.&lt;/b&gt; A unique numerical identifier for this object.&amp;#xA0; &lt;/li&gt;    &lt;li&gt;&lt;b&gt;Type ID.&lt;/b&gt; The identifier for the type of this object. &lt;/li&gt;    &lt;li&gt;&lt;b&gt;Object size.&lt;/b&gt; The size in bytes for this instance.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;In addition to these required elements, object records will have a variable number of additional elements describing the instances that the object references.&lt;/p&gt;  &lt;ul type="disc"&gt;   &lt;li&gt;&lt;b&gt;Referenced Object IDs.&lt;/b&gt; The identifiers for all objects that this object references.&amp;#xA0; &lt;/li&gt; &lt;/ul&gt;  &lt;p mce_keep="true"&gt;&amp;#xA0;&lt;/p&gt;  &lt;p&gt;An example with referenced object ids:&lt;/p&gt;  &lt;p&gt;o 1c15d2 3 1c 1c15db 1c15d8 1c15d5&lt;/p&gt;  &lt;p&gt;Notes:&lt;/p&gt;  &lt;ul type="disc"&gt;   &lt;li&gt;Object identifiers are not guaranteed to be unique across dump files.&amp;#xA0; This point is important for tools writers:&amp;#xA0; It is not possible to develop tools that identify trends across dump files because a given object instance in one dump isn't guaranteed to have the same identifier in a later dump of the same heap. &lt;/li&gt;    &lt;li&gt;The type record corresponding to a particular object record is not guaranteed to precede the object record in the dump file.&lt;/li&gt; &lt;/ul&gt;  &lt;h4&gt;Root Record&lt;/h4&gt;  &lt;p&gt;Root records identify GC roots.&amp;#xA0; Each root record contains 4 required elements:&lt;/p&gt;  &lt;ul type="disc"&gt;   &lt;li&gt;&lt;b&gt;The letter &amp;quot;r&amp;quot;.&lt;/b&gt;&amp;#xA0; Identifies the record as a root record. &lt;/li&gt;    &lt;li&gt;&lt;b&gt;Object ID.&lt;/b&gt; The identifier of the object that is this root. &lt;/li&gt;    &lt;li&gt;&lt;b&gt;Root kind.&lt;/b&gt; The reason this object instance is a root.&amp;#xA0; One of the following values:&lt;/li&gt; &lt;/ul&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;b&gt;1&lt;/b&gt; The object instance is a local variable.&lt;/p&gt;    &lt;p&gt;&lt;b&gt;2 &lt;/b&gt;The object instance is on the finalizer queue waiting for its finalizer to be run.&amp;#xA0; After the finalizer is run the object will be collected during the next GC.&lt;/p&gt;    &lt;p&gt;&lt;b&gt;3&lt;/b&gt; A GC handle exists which refers to the object instance (i.e System.Runtime.InteropServices.GCHandle)&lt;/p&gt;    &lt;p&gt;&lt;b&gt;4&lt;/b&gt; The object instance is a static variable.&lt;/p&gt;    &lt;p&gt;&lt;b&gt;5&lt;/b&gt; The object instance is a root specific to the Compact Framework's GC implementation.&amp;#xA0; Examples include interned strings or class descriptions. &lt;/p&gt;    &lt;p&gt;&lt;b&gt;0&lt;/b&gt; The object instance is rooted internally by the Compact Framework. Examples include object instances for application domains, assemblies, exceptions and so on.&lt;/p&gt; &lt;/blockquote&gt;  &lt;ul&gt;   &lt;li&gt;&lt;b&gt;Root flags.&lt;/b&gt; A set of flags providing more information about the root:&lt;/li&gt; &lt;/ul&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;b&gt;0x1.&lt;/b&gt; The root is pinned.&amp;#xA0; There are several cases in which a root may be pinned.&amp;#xA0; For example, the root may refer to managed objects that have been passed out to native code via PInvoke or COM interop, the root may be referenced by a GCHandle created with a GCHandleType of Pinned or a pointer in unsafe code points to the root.&amp;#xA0; &lt;/p&gt;    &lt;p&gt;The .Net Compact Framework CLR may also pin objects on your behalf as it runs your application.&amp;#xA0; The CLR will pin an object if it places a reference to that object in a register or refers to that object from the stack.&amp;#xA0; An object will also be pinned if a local variable or method argument points to a field within the object.&amp;#xA0; The CLR doesn't pin objects very often, but if one of the more obvious reasons don't explain why an object is pinned, it may be because of one of these &amp;quot;hidden&amp;quot; cases.&lt;/p&gt;    &lt;p&gt;&lt;b&gt;0x2.&lt;/b&gt; A GCHandle whose GCHandleType is Weak refers to the object.&lt;/p&gt;    &lt;p&gt;&lt;b&gt;0x4.&lt;/b&gt; The object is pointed to by a pointer in unsafe code or has a local variable or method argument points to a field within the object.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p mce_keep="true"&gt;If the root kind is static, the root record will have an additional element:&lt;/p&gt;  &lt;ul type="disc"&gt;   &lt;li&gt;&lt;b&gt;Root container.&lt;/b&gt;&amp;#xA0; The identifier of the type the static variable is contained in.&lt;/li&gt; &lt;/ul&gt;  &lt;p mce_keep="true"&gt;Here's a root record with the additional root container element:&lt;/p&gt;  &lt;p&gt;r b2753 4 0 13c&lt;/p&gt;  &lt;p mce_keep="true"&gt;&lt;b&gt;&lt;/b&gt;&amp;#xA0;&lt;/p&gt;  &lt;p mce_keep="true"&gt;&lt;/p&gt;  &lt;h4&gt;End AppDomain Record&lt;/h4&gt;  &lt;p&gt;End AppDomain records close the section initiated by a corresponding AppDomain record.&amp;#xA0;&amp;#xA0; End AppDomain records have three elements:&lt;/p&gt;  &lt;ul type="disc"&gt;   &lt;li&gt;&lt;b&gt;The letter &amp;quot;c&amp;quot;.&lt;/b&gt; Identifies the record as an end record &lt;/li&gt;    &lt;li&gt;&lt;b&gt;Application Name.&lt;/b&gt;&amp;#xA0; The name of the application from which this dump file was generated.&amp;#xA0; This name matches the name in the application record at the beginning of the file. &lt;/li&gt;    &lt;li&gt;&lt;b&gt;Timestamp.&lt;/b&gt;&amp;#xA0; The timestamp from the corresponding AppDomain record.&lt;/li&gt; &lt;/ul&gt;  &lt;p mce_keep="true"&gt;&amp;#xA0;&lt;/p&gt;  &lt;p mce_keep="true"&gt;Thanks,&lt;/p&gt;  &lt;p mce_keep="true"&gt;Steven&lt;/p&gt;  &lt;p mce_keep="true"&gt;&lt;span lang="EN" style="font-size: 10pt; line-height: 115%; font-family: &amp;#x27;Rockwell&amp;#x27;,&amp;#x27;serif&amp;#x27;; mso-ansi-language: en"&gt;This posting is provided &amp;quot;AS IS&amp;quot; with no warranties, and confers no rights.&lt;/span&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=5035606" width="1" height="1"&gt;</content><author><name>stevenpr</name><uri>http://blogs.msdn.com/members/stevenpr.aspx</uri></author></entry><entry><title>.Net Compact Framework: “Hey, what happened to the diagnostic tools?”</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/stevenpr/archive/2007/09/12/net-compact-framework-hey-what-happened-to-the-diagnostic-tools.aspx" /><id>http://blogs.msdn.com/stevenpr/archive/2007/09/12/net-compact-framework-hey-what-happened-to-the-diagnostic-tools.aspx</id><published>2007-09-13T03:33:00Z</published><updated>2007-09-13T03:33:00Z</updated><content type="html">&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;FONT size=3&gt;&lt;FONT face=Calibri&gt;If you’ve installed the Beta2 version of Orcas you may have noticed that the NetCF diagnostic tools&amp;nbsp;(RPM, CLRProfler, ...)&amp;nbsp;are missing.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Don’t worry, these haven’t been cut from Orcas, they will just be distributed via the web in a separate “power toys” pack.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;A CTP of these tools is now available at: &lt;SPAN style="COLOR: #1f497d"&gt;&lt;A href="http://www.microsoft.com/downloads/details.aspx?familyid=C8174C14-A27D-4148-BF01-86C2E0953EAB&amp;amp;displaylang=en"&gt;http://www.microsoft.com/downloads/details.aspx?familyid=C8174C14-A27D-4148-BF01-86C2E0953EAB&amp;amp;displaylang=en&lt;/A&gt;&lt;/SPAN&gt; .&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;This CTP works with Orcas Beta2.&lt;?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&lt;FONT face=Calibri size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;FONT size=3&gt;&lt;FONT face=Calibri&gt;We intend to distribute the final Power Toys release at the same time that Orcas ships.&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&lt;FONT face=Calibri size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;FONT size=3&gt;&lt;FONT face=Calibri&gt;Thanks,&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;FONT size=3&gt;&lt;FONT face=Calibri&gt;Steven&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;FONT size=3&gt;&lt;FONT face=Calibri&gt;&lt;/FONT&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;FONT size=3&gt;&lt;FONT face=Calibri&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Tahoma','sans-serif'; mso-ansi-language: EN-US; mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-fareast-language: EN-US; mso-bidi-language: AR-SA"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: 'Rockwell','serif'; mso-ansi-language: EN"&gt;This posting is provided "AS IS" with no warranties, and confers no rights.&lt;/SPAN&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=4886477" width="1" height="1"&gt;</content><author><name>stevenpr</name><uri>http://blogs.msdn.com/members/stevenpr.aspx</uri></author><category term="Diagnostics" scheme="http://blogs.msdn.com/stevenpr/archive/tags/Diagnostics/default.aspx" /></entry><entry><title>.Net Compact Framework Performance Webcast</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/stevenpr/archive/2007/08/14/net-compact-framework-performance-webcast.aspx" /><id>http://blogs.msdn.com/stevenpr/archive/2007/08/14/net-compact-framework-performance-webcast.aspx</id><published>2007-08-14T20:53:00Z</published><updated>2007-08-14T20:53:00Z</updated><content type="html">&lt;P&gt;Last week I did an MSDN webcast on writing high performing device applications using the .Net Compact Framework.&amp;nbsp; The webcast contains both in depth information on the internal workings of the Compact Framework and a set of tips and tricks for optimizing performance in everything from user interface to collections to networking.&amp;nbsp; Here's the URL&lt;SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Arial','sans-serif'"&gt;: &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Arial','sans-serif'"&gt;&lt;A title=http://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032345907&amp;amp;Culture=en-US href="http://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032345907&amp;amp;Culture=en-US" mce_href="http://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032345907&amp;amp;Culture=en-US"&gt;http://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032345907&amp;amp;Culture=en-US&lt;/A&gt;&amp;nbsp;.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;Also, I had promised those viewing the webcast live that I would post the "generics" slide without the performance numbers overlaying the code.&amp;nbsp; Here it is:&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;A title="Photo Sharing" href="http://www.flickr.com/photos/stevenjpr/1117072123/"&gt;&lt;IMG height=368 alt=Generics src="http://farm2.static.flickr.com/1268/1117072123_980031a705_o.jpg" width=492&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Thanks,&lt;/P&gt;
&lt;P&gt;Steven&lt;/P&gt;
&lt;P&gt;&lt;FONT size=1&gt;Disclaimer(s):&lt;BR&gt;This posting is provided "AS IS" with no warranties, and confers no rights.&lt;/FONT&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=4387014" width="1" height="1"&gt;</content><author><name>stevenpr</name><uri>http://blogs.msdn.com/members/stevenpr.aspx</uri></author><category term="NetCF General" scheme="http://blogs.msdn.com/stevenpr/archive/tags/NetCF+General/default.aspx" /></entry></feed>