PropertyDescriptor memory leak

Grids for WPF Forum

Posted 14 years ago by Craig - Varigence, Inc.
Version: 10.1.0521
Platform: .NET 4.0
Environment: Windows 7 (32-bit)
Avatar
Using the ANTS memory profiler, I'm seeing a memory leak being caused by the property grid. I believe the simplified scenario is as follows:

1. Have an application with a TreeView (in our case, our TreeView is populated with ViewModels via HierarchicalDataTemplates).
2. Have a property grid (in a ToolWindow) whose SelectedObject binding is:

SelectedObject="{Binding ElementName=treeView, Path=SelectedItem, Mode=OneWay}"
3. Run the application in a memory profiler (in my case, ANTS)
4. Close the tool window and you'll see the following references lingering:

One originates from the ReflectTypeDescriptionProvider._propertyCache. It has a HashTable that contains a PropertyDescriptor array. The array itself contains ReflectPropertyDescriptor objects, one of which has a valueChangedHandler which ends up referencing the last item that appeared in the property grid.

The other is similar but comes from TypeDescriptor._providerTable and has a longer reference path, but still ends up pointing to a ReflectPropertyDescriptor whose valueChangedHandler ends up reference the last item to appear in the property grid.

When I remove the property grid from my application, I don't see any of these lingering references so I'm pretty convinced the grid is responsible. I wonder if this issue is related to this problem: http://support.microsoft.com/kb/938416/en-us

Please let me know if you need more information. Thanks,

-Craig

Comments (6)

Posted 14 years ago by Craig - Varigence, Inc.
Avatar
Just wondering if you've found anything, or have any word on this issue.

Thanks again,

-Craig

[Modified at 05/04/2010 02:20 AM]
Posted 14 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar
Hi Craig,

I apologize, we never received notification of your post. We had some problems with our email server last week, so that may have been the issue.

Can you please put together a small sample project and email it over?

[Modified at 05/04/2010 07:40 AM]


Actipro Software Support

Posted 14 years ago by Craig - Varigence, Inc.
Avatar
I have a sample ready that I'll be sending over. It seems that the problem is caused when a class implements INotifyPropertyChanged and/or stores a field/property of the same type as itself.
Posted 14 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar
Hi Craig,

Unfortunately, we're not seeing the same thing you described. We normally use Scitech's memory profiler (www.memprofiler.com), not Red Gate's. Scitech's is better at cutting out the "noise", or paths that are not the real cause of an object being rooted. We do see one instance of the ProjectViewModel being retained, but the root paths all pass through the TreeView, specifically:

Namespace Name Instance/Field/Method
DataGridCleanupRepro BViewModel #1,333._treeParent
System.Windows EffectiveValueEntry[] #22,830[28]._value
System.Windows.Controls TreeView #544._effectiveValues
DataGridCleanupRepro Window1 #372.treeView
DataGridCleanupRepro App #3._mainWindow

I tried Red Gate's version as a trial and came up with similar results. If I cut out the PropertyGrid, the TreeView still holds the reference using the same root path listed above.


Actipro Software Support

Posted 14 years ago by Craig - Varigence, Inc.
Avatar
So, I contacted SciTech regarding this issue as I wanted to better understand the difference between the ANTS results I was seeing and the results from SciTech's profiler. Accoridng to SciTech, the reason the paths weren't displayed is that collecting a snapshot performs multiple GCs and waits for finalization and, during finalization, event handlers are removed.

Subsequently, it seems like my best bet is to manually invoke a GC collect and wait for finalizer cleanup when closing my project. As long as this occurs after the property grid is cleared, the references I was seeing appear to vanish.
Posted 14 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar
Hi Craig,

When using SelectedObject(s), the PropertyGrid uses PropertyDescriptor (a .NET class) to access the property and it's metadata. In addition, it will add change handlers using PropertyDescriptor.AddValueChanged, so it will be notified if the property changes (assuming the required plumbing is implemented in the associated class).

When the change handler is added the PropertyDescriptorAccessor (a PropertyGrid class that wraps PropertyDescriptor), could be rooted if the property is a DependencyProperty. Even if the property wasn't a DependencyProperty, the PropertyDescriptorAccessor could be retained for the life of the SelectedObject(s). So if the PropertyGrid was "refreshed" any old PropertyDescriptorAccessor would not be cleaned up.

To work around both these issues, we created a secondary helper class that is used in the AddValueChanged call. The PropertyDescriptorAccessor would hold a reference to this helper class and "unhook" it when the PropertyDescriptorAccessor is finalized. This fixes both issues described above, but doesn't not clean up everything in a single GC cleanup pass. We previously tried a WeakEventManager, but ran into problems with it.

So it sounds like SciTech is performing additional "cleanup" steps before taking a snapshot (by default), to weed out any false positives. The objects here are being cleaned up, but it sounds like Red Gate is taking a snapshot before that has executed.


Actipro Software Support

The latest build of this product (v24.1.2) was released 2 days ago, which was after the last post in this thread.

Add Comment

Please log in to a validated account to post comments.