<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>.NET and Memory</title>
	<atom:link href="http://www.scitech.se/blog/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://www.scitech.se/blog</link>
	<description>Information and comments about .NET, memory profiling and development in general&#60;br&#62;by Andreas Suurkuusk, co-founder of SciTech Software AB</description>
	<lastBuildDate>Mon, 05 Sep 2011 06:50:40 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>.NET Memory Profiler 4.0 Released</title>
		<link>http://www.scitech.se/blog/?p=106</link>
		<comments>http://www.scitech.se/blog/?p=106#comments</comments>
		<pubDate>Mon, 05 Sep 2011 06:50:40 +0000</pubDate>
		<dc:creator>Andreas Suurkuusk</dc:creator>
				<category><![CDATA[.NET Memory Profiler Features]]></category>
		<category><![CDATA[.NET Memory Profiler Releases]]></category>

		<guid isPermaLink="false">http://www.scitech.se/blog/?p=106</guid>
		<description><![CDATA[I am happy to announce that we released .NET Memory Profiler 4.0 a few weeks ago. This version includes several new features and improvements, such as: Instance graph Get a visual overview of how a managed instance is being used, how it is related to other instances, and, maybe most importantly, how roots are preventing [...]]]></description>
			<content:encoded><![CDATA[<p>I am happy to announce that we released .NET Memory Profiler 4.0 a few weeks ago. This version includes several new<br />
features and improvements, such as:</p>
<ul>
<li><strong>Instance graph</strong><br />
<em>Get a visual overview of how a managed instance is being used,<br />
how it is related to other instances, and, maybe most importantly,<br />
how roots are preventing it from being garbage collected.</em></li>
<li><strong>Instance and allocation filters</strong><br />
<em>The new filters provide you with information about instances and allocations that share a common<br />
characteristic, e.g. all allocations and instances that are derived from a specific type, all<br />
instances that are directly referenced by a root, all boxed instances,<br />
or all allocations performed by a specific method.</em></li>
<li><strong>Guided profiling</strong><br />
<em>The profiler guides provide interactive step-by-step instructions that will help you with common memory profiling tasks, such as memory leak investigations.</em></li>
</ul>
<p>This is just a few of the new features and improvements. For more information, please visit the <a style="color: #336699; font-weight: normal; text-decoration: underline;" href="http://memprofiler.com">.NET Memory Profiler website</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.scitech.se/blog/?feed=rss2&#038;p=106</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>.NET Memory Profiler 4.0 Beta Released</title>
		<link>http://www.scitech.se/blog/?p=103</link>
		<comments>http://www.scitech.se/blog/?p=103#comments</comments>
		<pubDate>Thu, 09 Jun 2011 14:20:50 +0000</pubDate>
		<dc:creator>Andreas Suurkuusk</dc:creator>
				<category><![CDATA[.NET Memory Profiler Releases]]></category>

		<guid isPermaLink="false">http://www.scitech.se/blog/?p=103</guid>
		<description><![CDATA[Now we have released .NET Memory Profiler 4.0 Beta. As mentioned previously, .NET Memory Profiler 4.0 is a significant improvement over the previous version. You can read more about it on the beta page. If you are using or evaluating .NET Memory Profiler, I highly recommend that you download this beta; it has been pretty [...]]]></description>
			<content:encoded><![CDATA[<p>Now we have released .NET Memory Profiler 4.0 Beta. As mentioned previously, .NET Memory Profiler 4.0 is a significant improvement over the previous version. You can read more about it on the<a href="http://memprofiler.com/beta"> beta page</a>.</p>
<p>If you are using or evaluating .NET Memory Profiler, I highly recommend that you download this beta; it has been pretty thoroughly tested and there are no significant known problems. If you have a current license of .NET Memory Profiler 3.x, you can use your registration key for the  4.0 beta as well. If you purchase .NET Memory Profiler 3.5 today (or if you have purchased v3.5 on or after September 27th, 2010), you will get a free upgrade to version 4.0 as soon as it is released.</p>
<p>We&#8217;re currently updating the documentation and finalizing the new licensing system. As soon as this is finished and, of course, when we have fixed any reported errors, we will release the final version of .NET Memory Profiler 4.0. Hopefully it will not take too long. It has taken much longer to develop the new version than we originally planned, but on the other hand, there are also  many new features and improvements that were  not included in our original plan. I hope you will like this new version an find the new features useful.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.scitech.se/blog/?feed=rss2&#038;p=103</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>.NET Memory Profiler 4.0 Preview 3 Released</title>
		<link>http://www.scitech.se/blog/?p=96</link>
		<comments>http://www.scitech.se/blog/?p=96#comments</comments>
		<pubDate>Fri, 14 Jan 2011 13:34:49 +0000</pubDate>
		<dc:creator>Andreas Suurkuusk</dc:creator>
				<category><![CDATA[.NET Memory Profiler Releases]]></category>

		<guid isPermaLink="false">http://www.scitech.se/blog/?p=96</guid>
		<description><![CDATA[We have just released the third preview of .NET Memory Profiler 4.0. .NET Memory Profiler 4.0 includes significant improvements over .NET Memory Profiler 3.5, such as a new instance graph, Silverlight support, and improved user interface and better performance. For more information and to download the preview,visit the preview page. Even though version 4.0 is [...]]]></description>
			<content:encoded><![CDATA[<p>We have just released the third preview of .NET Memory Profiler 4.0. .NET Memory Profiler 4.0 includes significant improvements over .NET Memory Profiler 3.5, such as a new instance graph, Silverlight support, and improved user interface and better performance. For more information and to download the preview,visit the <a title=".NET Memory Profiler 4.0 Preview" href="http://memprofiler.com/preview">preview page</a>.</p>
<p>Even though version 4.0 is still missing a few major features, this preview has been pretty thouroughly tested and is probably stable enough for most users.  If you are evaluating .NET Memory Profiler, I highly recommend that you try the new version instead of the official 3.5 version. There are several reasons for trying the new version:</p>
<ul>
<li>The new instance graph makes it much easier to investigate how an instance is being used and what&#8217;s preventing it from being garbage collected.</li>
<li>The instance tracker (which, for instance, keeps track of the allocation call stacks of specific instances), has a new implementation. This has reduced the memory usage and improved the performance of the profiler. The new profiling levels also makes it easier to strike a balance between performance/memory usage and the amount of information presented.</li>
<li>Support for Silverlight profiling has been improved, making it much easier to profiler Silverlight application (version 3.5 doesn&#8217;t actually include a &#8220;Profile Silverlight&#8221; option, even though it is possible to manually profile Silverlight applications).</li>
<li>DependencyProperty evaluation makes it much easier to see relationships between DependencyObjects in a WPF application (Silverlight DependencyProperty evaluation is coming soon).</li>
<li>Attaching the profiler to a running process is much faster and more stable, by using the new API provided by .NET Framework 4.0.</li>
<li><strong>The upgrade to version 4.0 is free of charge for anyone who has purchased .NET Memory Profiler 3.5 on or after September 27th, 2010.</strong></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.scitech.se/blog/?feed=rss2&#038;p=96</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>.NET Memory Profiler 3.5.150 Released</title>
		<link>http://www.scitech.se/blog/?p=87</link>
		<comments>http://www.scitech.se/blog/?p=87#comments</comments>
		<pubDate>Tue, 25 May 2010 19:44:39 +0000</pubDate>
		<dc:creator>Andreas Suurkuusk</dc:creator>
				<category><![CDATA[.NET Memory Profiler Releases]]></category>

		<guid isPermaLink="false">http://www.scitech.se/blog/?p=87</guid>
		<description><![CDATA[Today we released a maintenance version of .NET Memory Profiler. If you are profiling .NET 1.x applications, or if you are profiling ASP.NET applications on a system with .NET 4.0 installed, it is highly recommended that you download this release. The previous installer was missing a file which caused problems with the dispose tracker when [...]]]></description>
			<content:encoded><![CDATA[<p>Today we released a maintenance version of .NET Memory Profiler. If you are profiling .NET 1.x applications, or if you are profiling ASP.NET applications on a system with .NET 4.0 installed, it is highly recommended that you download this release. The previous installer was missing a file which caused problems with the dispose tracker when profiling .NET 1.x applications. More importantly, the previous version didn&#8217;t detect the Web development server (WebDev.WebServer) included with .NET 4.0. This version detects both version 2.0 and 4.0 of WebDev.WebServer and allows you to select which one to use when profiling an ASP.NET application. For more information about this release, and other maintenance releases, please read the <a title=".NET Memory Profiler release notes" href="http://memprofiler.com/releasenotes.aspx">release notes</a>. The latest version can be downloaded from the <a title=".NET Memory Profiler download" href="http://memprofiler.com/download.aspx">download page</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.scitech.se/blog/?feed=rss2&#038;p=87</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Memory Profiling SQL Server</title>
		<link>http://www.scitech.se/blog/?p=89</link>
		<comments>http://www.scitech.se/blog/?p=89#comments</comments>
		<pubDate>Tue, 25 May 2010 12:46:41 +0000</pubDate>
		<dc:creator>Andreas Suurkuusk</dc:creator>
				<category><![CDATA[.NET Memory Profiler FAQ]]></category>

		<guid isPermaLink="false">http://www.scitech.se/blog/?p=89</guid>
		<description><![CDATA[One profiling scenario that is currently not supported by .NET Memory Profiler is SQL Server profiling. If your SQL Server database contains any .NET stored procedures or any other .NET code it can be important to validate the memory usage of the .NET code, especially if any state is kept by the .NET code. As [...]]]></description>
			<content:encoded><![CDATA[<p>One profiling scenario that is currently not supported by .NET Memory Profiler is SQL Server profiling. If your SQL Server database contains any .NET stored procedures or any other .NET code it can be important to validate the memory usage of the .NET code, especially if any state is kept by the .NET code. As soon as any state information is kept in memory, there is a risk of memory leaks.</p>
<p>As the SQL Server is running as a Windows service, the Profile service command should be used, as described below:</p>
<ol>
<li>Start .NET Memory Profiler as an adminstrator (e.g. right click and select &#8220;Run as administrator&#8221;)</li>
<li>Select Profile Service</li>
<li>Find the correct SQL Server service</li>
<li>Start profiling</li>
<li>The SQL Server service will be restarted and you will see the message &#8220;Waiting for profiled process to start&#8221;.</li>
<li>Make sure that the .NET runtime is loaded into the process, e.g. by executing a stored procedure. This should cause the message to disappear and the profiling to start.</li>
</ol>
<p>Unfortunately, this will not work! You will soon receive an error message stating:</p>
<blockquote><p>System.IO.FileNotFoundException: Could not load file or assembly &#8216;SciTech.NetMemProfiler.InstrumentationHelper2, Version=3.1.0.0, Culture=neutral, PublicKeyToken=2dc3dfad160eda83&#8242; or one of its dependencies. The system cannot find the file specified. </p></blockquote>
<p>The problem is that the dispose tracker (which is usually enabled) requires a helper assembly. This assembly is installed in the GAC, but SQL Server will not load this assembly. The solution is to add the helper assembly to the database. But there&#8217;s one more gotcha. The helper assembly performs native functions calls, and thus requires unrestricted permissions, i.e. it must be added with PERMISSION_SET = UNSAFE. In order to do this, the database needs to be marked as &#8220;Trustworthy&#8221; (which is not recommended), or a database login with UNSAFE ASSEMBLY rights must be created for the helper assembly. The login can be created using the following SQL script:</p>
<pre>USE master
GO
IF NOT EXISTS (SELECT name FROM master.sys.asymmetric_keys WHERE name = 'MemProfilerInstrumentationKey')
begin
  CREATE ASYMMETRIC KEY MemProfilerInstrumentationKey
    FROM EXECUTABLE FILE = 'C:Program filesSciTechNetMemProfiler3AssembliesSciTech.NetMemProfiler.InstrumentationHelper2.dll'
  CREATE LOGIN MemProfilerInstrumentationLogin
    FROM ASYMMETRIC KEY MemProfilerInstrumentationKey
  GRANT UNSAFE ASSEMBLY TO MemProfilerInstrumentationLogin
end<span style="font-size: x-small;"> </span></pre>
<p>After the login has been created, the assembly can be added with unrestricted permissions. It must be added to each database that includes .NET code that will be profiled, using the SQL script below.</p>
<pre>USE [&lt;Database name&gt;]
CREATE ASSEMBLY [SciTech.NetMemProfiler.InstrumentationHelper2]
  FROM 'C:Program filesSciTechNetMemProfiler3AssembliesSciTech.NetMemProfiler.InstrumentationHelper2.dll'
  WITH PERMISSION_SET = UNSAFE;</pre>
<p> Now it should be possible to profile .NET code hosted by SQL Server. Just follow the steps from the beginning of this post.</p>
<p>Once you have finished profiling, the permissions granted to the profiler can be removed by dropping the assembly, login, and asymmetric key:</p>
<pre>USE [&lt;Database name&gt;]
DROP ASSEMBLY [SciTech.NetMemProfiler.InstrumentationHelper2]
GO
USE master
DROP LOGIN MemProfilerInstrumentationLogin
DROP ASYMMETRIC KEY MemProfilerInstrumentationKey</pre>
<p>Admittedly these requirements make it a bit cumbersome to profile SQL Server hosted .NET code. The next version of the profiler will include an option to &#8220;Profile SQL Server&#8221;, which will automatically prepare the database for profiling.</p>
<p> </p>
<p>Thanks to Gerhard Obenaus at Blackbaud, Inc. for pointing out how to create a login for the helper assembly, instead of using the &#8220;Trustworthy&#8221; alternative.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.scitech.se/blog/?feed=rss2&#038;p=89</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>.NET Memory Profiler 3.5.130 Released</title>
		<link>http://www.scitech.se/blog/?p=86</link>
		<comments>http://www.scitech.se/blog/?p=86#comments</comments>
		<pubDate>Wed, 13 Jan 2010 21:38:52 +0000</pubDate>
		<dc:creator>Andreas Suurkuusk</dc:creator>
				<category><![CDATA[.NET Memory Profiler Releases]]></category>

		<guid isPermaLink="false">http://www.scitech.se/blog/?p=84</guid>
		<description><![CDATA[Yesterday we published a maintenance release of .NET Memory Profiler 3.5 (version 3.5.130). This release contains several important fixes, so it is recommended that you download an install this release if you have an older version installed. For instance, due to refactorings in the previous release, native stack walking failed to use symbols from the [...]]]></description>
			<content:encoded><![CDATA[<p>Yesterday we published a maintenance release of .NET Memory Profiler 3.5 (version 3.5.130). This release contains several important fixes, so it is recommended that you download an install this release if you have an older version installed. For instance, due to refactorings in the previous release, native stack walking failed to use symbols from the Microsoft symbol store, which caused the native allocation call stacks to be much less detailed. We have also improved the performance when working with very large snapshots, and the memory usage has been reduced somewhat. Still, to avoid out of memory problems, it is recommended that the 64-bit version of .NET Memory Profiler is used when profiling applications with high memory usage. The 64-bit version is automatically used when the standalone profiler is used on a 64-bit operating, but since Visual Studio is a 32-bit process, the integrated profiler will only run as 32-bit.</p>
<p>The latest release can be downloaded from the <a title=".NET Memory Profiler download" href="http://memprofiler.com/download.aspx">Download page</a>, and more information about the release is available in the <a title=".NET Memory Profiler release notes" href="http://memprofiler.com/releasenotes.aspx">release notes</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.scitech.se/blog/?feed=rss2&#038;p=86</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>.NET Memory Profiler 3.5 Released</title>
		<link>http://www.scitech.se/blog/?p=78</link>
		<comments>http://www.scitech.se/blog/?p=78#comments</comments>
		<pubDate>Thu, 15 Oct 2009 08:09:25 +0000</pubDate>
		<dc:creator>Andreas Suurkuusk</dc:creator>
				<category><![CDATA[.NET Memory Profiler Releases]]></category>

		<guid isPermaLink="false">http://www.scitech.se/blog/?p=78</guid>
		<description><![CDATA[Finally! Last week we launched .NET MemoryProfiler 3.5. It has taken a while to finish this version, but I&#8217;m very pleased with the result. For more information about this version, and to download it, please visit the .NET Memory Profiler site.]]></description>
			<content:encoded><![CDATA[<p>Finally! Last week we launched .NET MemoryProfiler 3.5. It has taken a while to finish this version, but I&#8217;m very pleased with the result. For more information about this version, and to download it, please visit the <a title=".NET Memory Profiler" href="http://memprofiler.com">.NET Memory Profiler site</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.scitech.se/blog/?feed=rss2&#038;p=78</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>.NET Memory Profiler 3.5 Beta Released</title>
		<link>http://www.scitech.se/blog/?p=76</link>
		<comments>http://www.scitech.se/blog/?p=76#comments</comments>
		<pubDate>Mon, 07 Sep 2009 09:47:16 +0000</pubDate>
		<dc:creator>Andreas Suurkuusk</dc:creator>
				<category><![CDATA[.NET Memory Profiler Releases]]></category>

		<guid isPermaLink="false">http://www.scitech.se/blog/?p=76</guid>
		<description><![CDATA[It took much longer than planned, but now we have released .NET Memory Profiler 3.5 Beta. It contains significant improvement over the preview, such as a call stack reducer, significantly faster loading and saving of session files, the possibility to ignore analysis issues and support for .NET Framework 4.0. This beta is more or less feature complete [...]]]></description>
			<content:encoded><![CDATA[<p>It took much longer than planned, but now we have released .NET Memory Profiler 3.5 Beta. It contains significant improvement over the preview, such as a call stack reducer, significantly faster loading and saving of session files, the possibility to ignore analysis issues and support for .NET Framework 4.0. This beta is more or less feature complete and we expect to release the final version of .NET Memory Profiler 3.5 before the end of September. For more information about the beta and to download it, please visit the beta page at <a href="http://memprofiler.com/beta">http://memprofiler.com/beta</a>. If you have any comments about the new version, you can comment in this blog, or send an e-mail to <a href="mailto:memprofiler@scitech.se">memprofiler@scitech.se</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.scitech.se/blog/?feed=rss2&#038;p=76</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Resource Leak in TreeView</title>
		<link>http://www.scitech.se/blog/?p=20</link>
		<comments>http://www.scitech.se/blog/?p=20#comments</comments>
		<pubDate>Mon, 06 Apr 2009 08:43:59 +0000</pubDate>
		<dc:creator>Andreas Suurkuusk</dc:creator>
				<category><![CDATA[.NET Framework]]></category>
		<category><![CDATA[.NET Memory Profiler Features]]></category>

		<guid isPermaLink="false">http://www.scitech.se/blog/?p=20</guid>
		<description><![CDATA[I&#8217;m planning to restart this blog by writing a few posts about the new features in .NET Memory Profiler  3.5. I&#8217;ll start of by investigating a resource leak in the .NET Framework. I discovered this leak almost a year ago as I investigated memory problems reported by a user (in our support forum). To illustrate [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m planning to restart this blog by writing a few posts about the new features in .NET Memory Profiler  3.5. I&#8217;ll start of by investigating a resource leak in the .NET Framework.</p>
<p>I discovered this leak almost a year ago as I investigated memory problems reported by a user (<a href="http://memprofiler.com/forum/viewtopic.php?t=1254">in our support forum</a>). To illustrate the leak, I have created a very simple Windows Forms application, with a form that contains a single button. In the Click handler of the button,  a number of TreeViews are created and the Checkboxes are enabled. They are added to the form, just to make sure that they will be fully initialized and then immediately disposed.</p>
<pre>private void button1_Click( object sender, EventArgs e )
{
   for( int i = 0; i &lt; 100; i++ )
   {
      using( TreeView treeView = new TreeView() )
      {
         this.Controls.Add( treeView );
         treeView.CheckBoxes = true;
      }
   }
}</pre>
<p>This should not cause any left over instances; neither managed memory instances nor unmanaged resource instances. But when testing this under the profiler, the following results can be seen (after collecting a snapshot before and after a button click).</p>
<p><img class="alignnone" style="max-width: 533px;" title="Second snapshot" src="/blog/images/secondsnapshot.png" alt="" width="533" height="316" /></p>
<p>There are 200 new HBITMAPs and HDCs, and 100 new HIMAGELISTs! Considering that we created 100 TreeViews, it seems very likely that the new resource instances are related to them. Let&#8217;s investigate one of the resource further, for example the HBITMAPs. The allocation call stacks of the bitmaps provide the following information:</p>
<p><img class="alignnone" style="max-width: 545px;" title="Bitmap allocation stack" src="/blog/images/bitmapallocation.png" alt="" width="545" height="706" /></p>
<p>Thanks to the improved native stacks in .NET Memory Profiler 3.5, you can easily see that the HBITMAP is created as part of an ImageList, when initializing the checkboxes in the native TreeView (TV_InitCheckBoxes). So setting the CheckBoxes property to true, caused the HBITMAP to be created, but why is it not released? At first I suspected that there was actually a resource leak in the native Win32 TreeView implementation, but when checking the documentation, I found this:</p>
<blockquote><p>Once a tree-view control is created with this style, the style cannot be removed. Instead, you must destroy the control and create a new one in its place. Destroying the tree-view control does not destroy the check box state image list. You must destroy it explicitly. Get the handle to the state image list by sending the tree-view control a <span style="text-decoration: underline;"><span style="color: #0000ff;">TVM_GETIMAGELIST</span></span> message. Then destroy the image list with <span style="text-decoration: underline;"><span style="color: #0000ff;">ImageList_Destroy</span></span>.</p></blockquote>
<p>Apparantly, it&#8217;s the responsibility of the user of the native TreeView (e.g. the .NET TreeView control) to release the image list. I find this a bit odd since this image list is created as a side-effect of the internal implementation of the check boxes. Anyway, it seems like the .NET TreeView control fails to release the image list. To fix this leak, the image-list must be explicility released. The ReleaseCheckBoxImageList method below shows an example on how this can be done.</p>
<pre>static class TreeViewHelper
{
   ///
   /// Releases the checkbox image list in the
   /// specified TreeView.
   ///
   internal static void ReleaseCheckBoxImageList(TreeView treeView)
   {
      if( treeView.IsHandleCreated )
      {
         int style = GetWindowLong( treeView.Handle, GWL_STYLE );

         if( (style &amp; TVS_CHECKBOXES) != 0 )
         {
            // Checkboxes were enabled in the
            // tree view. Let's destroy the
            // image list.
            IntPtr hStateImageList = SendMessage(
               treeView.Handle,
               TVM_GETIMAGELIST,
               (IntPtr)TVSIL_STATE,
               IntPtr.Zero );

            if( hStateImageList != IntPtr.Zero )
            {
               ImageList_Destroy( hStateImageList );
            }
         }
      }
   }

   #region Windows interop

   const int TV_FIRST = 0x1100;
   const int TVM_GETIMAGELIST = (TV_FIRST + 8);
   const int TVSIL_STATE = 2;
   const int TVS_CHECKBOXES = 0x0100;

   const int GWL_STYLE = (-16);

   [DllImport( "User32" )]
   static extern IntPtr SendMessage(
      IntPtr hWnd, int Msg,
      IntPtr wParam, IntPtr lParam);

   [DllImport( "User32" )]
   static extern int GetWindowLong(
      IntPtr hWnd, int nIndex);

   [DllImport( "comctl32" )]
   [return: MarshalAs( UnmanagedType.Bool )]
   static extern bool ImageList_Destroy(IntPtr himl);

   #endregion
}</pre>
<p>This method should be called when the image list will no longer be needed, for instance when the window handle is destroyed. The FixedTreeView class below shows how this can be implemented:</p>
<pre>///
/// A TreeView that properly releases
/// native Win32 resources.
///
class FixedTreeView : TreeView
{
   ///
   /// Overridden to make sure that the native
   /// checkbox image list is properly released.
   ///
   protected override void OnHandleDestroyed(EventArgs e)
   {
      TreeViewHelper.ReleaseCheckBoxImageList( this );

      base.OnHandleDestroyed( e );
   }
}</pre>
<p>By using the FixedTreeView instead of the standard TreeView, the test program no longer has a resource leak (or memory leak).</p>
<p><img class="alignnone" style="max-width: 584px;" title="Send snapshot with FixedTreeView" src="/blog/images/secondsnapshot-noleak.png" alt="" width="584" height="216" /></p>
<p>As you can see, this fixed the resource leak of HBITMAPs, HIMAGELISTs, HDCs, and even the HeapAlloced memory.</p>
<p>An additional bonus is that this fix will also handle the case where the CheckBoxes property is toggled.  When the CheckBoxes property is set to false, the image list should also be released. Thanks to the fact that the native TreeView must be recreated whenever the checkbox style is updated, the handle will be destroyed when the CheckBoxes property is changed and the fix will executed (<em>&#8220;Once a tree-view control is created with this style, the style cannot be removed. Instead, you must destroy the control and create a new one in its place&#8221;</em>).</p>
<p>The code in the forum post mentioned in the beginning didn&#8217;t handle this correctly, since it used the CheckBoxes property to decide if the image list should be released. This property don&#8217;t reflect the whether checkboxes were included in the control being destroyed. Therefore the TVS_CHECKBOXES style is checked instead, as that will handle setting CheckBoxes to false as well.</p>
<p>A beta of .NET Memory Profiler 3.5 will soon be released, but in the meantime you can test the improved native call stacks by downloading the <a href="http://memprofiler.com/preview">.NET Memory Profiler 3.5 preview</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.scitech.se/blog/?feed=rss2&#038;p=20</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>.NET Memory Profiler 3.5 Preview Released</title>
		<link>http://www.scitech.se/blog/?p=19</link>
		<comments>http://www.scitech.se/blog/?p=19#comments</comments>
		<pubDate>Tue, 17 Feb 2009 18:50:24 +0000</pubDate>
		<dc:creator>Andreas Suurkuusk</dc:creator>
				<category><![CDATA[.NET Memory Profiler Releases]]></category>

		<guid isPermaLink="false">http://www.scitech.se/blog/index.php/2009/02/17/net-memory-profiler-35-preview-released/</guid>
		<description><![CDATA[We didn&#8217;t quite make it within two weeks as I wrote in my last post, but now .NET Memory Profiler 3.5 Preview has been released. For more information and to download the preview, visit the .NET Memory Profiler 3.5 Preview page. If you have any comments, questions, or bug reports, we would like to hear [...]]]></description>
			<content:encoded><![CDATA[<p>We didn&#8217;t quite make it within two weeks as I wrote in my last post, but now .NET Memory Profiler 3.5 Preview has been released. For more information and to download the preview, visit the <a href="http://memprofiler.com/preview">.NET Memory Profiler 3.5 Preview</a> page. If you have any comments, questions, or bug reports, we would like to hear about them. Please send any feedback you have to <a href="mailto:memprofiler@scitech.se">memprofiler@scitech.se</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.scitech.se/blog/?feed=rss2&#038;p=19</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

