Control.ControlNativeWindow in the finalizer queue

Use this forum to read, ask or inform about memory issues in the .NET Framework and third party components.

Moderator: SciTech Software

Control.ControlNativeWindow in the finalizer queue

Postby donw146 » Thu Feb 13, 2014 10:08 pm

The problem I am seeing many times in my most recent profiler run with version 4.6.68, .Net 4.5, VS 2012 and Windows 7 64-bit is described below based on the instance graph. I have a custom control, which inherits from UserControl, which is marked as disposed in the graph. It show a reference through the private member variable Control.window to a Control.ControlNativeWindow object which is owned by the finalizer queue. It is my understanding that Dispose should have called GC.SuppressFinalize() and that this situation should not be occurring. There are so many issues listed in the profiler run that come down to a Control.ControlNativeWindow object rooted by the finalizer queue that it is almost impossible to find real leaks.

Is this a bug?

Any suggestions on how to avoid this problem?
donw146
 
Posts: 4
Joined: Thu Feb 13, 2014 9:49 pm
Location: Canada

Re: Control.ControlNativeWindow in the finalizer queue

Postby Andreas Suurkuusk » Fri Feb 14, 2014 3:02 pm

We're not aware of any bug that would cause the profiler to falsely indicate that a Control.ControlNativeWindow instance is referenced by the finalizer queue. Can you check the suppressedGC field of the Control.ControlNativeWindow instance? If this is true, the NativeWindow should probably not be in the finalizer queue.

I don't fully understand how the UserControl is referenced from the finalizer queue, could you provide a screenshot of the instance graph, or a root path so that I can get a better idea.
Best regards,

Andreas Suurkuusk
SciTech Software AB
Andreas Suurkuusk
 
Posts: 964
Joined: Wed Mar 02, 2005 7:53 pm
Location: Sweden

Re: Control.ControlNativeWindow in the finalizer queue

Postby donw146 » Fri Feb 14, 2014 4:01 pm

The suppressedGC field of the Control.ControlNativeWindow instance is false. Pictures are attached:
Attachments
Capture.PNG
Instance graph
Capture.PNG
suppressedGC
donw146
 
Posts: 4
Joined: Thu Feb 13, 2014 9:49 pm
Location: Canada

Re: Control.ControlNativeWindow in the finalizer queue

Postby Andreas Suurkuusk » Mon Feb 17, 2014 2:58 pm

The fact that suppressedGC is false indicates that the Control.ControlNativeWindow instances are eligible for finalization. I'm not sure why the finalization has not been suppressed since you have called Dispose on the owner Control. Maybe the window handle is being recreated while disposing. If the window handle is recreated, the Control.ControlNativeWindow will be re-registered for finalization (and suppressedGC will be set to false). Maybe you can investigate handle creation and destruction for your control instances and see if the handles are inadvertently recreated.

The instance graph you attached does not show the additional roots for the Control.ControlNativeWindow instance. Could you attach a copy of the full instance graph? You can use Ctrl-C or Edit->Copy to copy the graph to the clipboard as a bitmap (it can become quite big).

Do you have other types of instances in the finalizer queue, in addition to the native window instances?
Best regards,

Andreas Suurkuusk
SciTech Software AB
Andreas Suurkuusk
 
Posts: 964
Joined: Wed Mar 02, 2005 7:53 pm
Location: Sweden

Re: Control.ControlNativeWindow in the finalizer queue

Postby donw146 » Tue Feb 18, 2014 9:16 pm

I've made some fixes and ran the profiler again since my last post. The problem appears to be fixed and, while I have a theory about why it worked, I'd like your opinion. While the custom controls I posted about had to have a properly implemented public Dispose() method since they inherited it, I realized that we had a fairly large number of custom classes where we had implemented IDisposable from scratch. I checked the public Dispose() methods and, in many cases, we had not ended with GC.SuppressFinalize(). I added it and reran the test to see the original problem gone. My theory is that we were clogging up the finalizer queue with disposed objects and somehow affected the controls as well.
donw146
 
Posts: 4
Joined: Thu Feb 13, 2014 9:49 pm
Location: Canada

Re: Control.ControlNativeWindow in the finalizer queue

Postby Andreas Suurkuusk » Wed Feb 19, 2014 5:06 pm

Yes, if you create a lot of instances that will be queued for finalization, there is a risk that the finalization of instances will be delayed.

Still, the Control.ControlNativeWindow instances should normally not be queued for finalization if they are properly disposed. Did you check whether you have Controls that somehow gets recreated?

Also note that you normally don't need to create finalizable classes. If you are wrapping an unmanaged resource, you can often use an existing SafeHandle class or create your own SafeHandle derived class.If you are not wrapping unmanaged resources, there's seldom a need to implement a finalizer.
Best regards,

Andreas Suurkuusk
SciTech Software AB
Andreas Suurkuusk
 
Posts: 964
Joined: Wed Mar 02, 2005 7:53 pm
Location: Sweden

Re: Control.ControlNativeWindow in the finalizer queue

Postby donw146 » Wed Feb 19, 2014 9:33 pm

Thanks for your feedback.

I guess the Control.ControlNativeWindow instances previously being queued for finalization will remain a mystery. I did not knowingly fix any problem where the controls were being recreated. I've seen no sign of the problem since I did the GC.SuppressFinalize cleanup.

I should also mention that almost none of our IDIsposable classes had finalizers. As part of the cleanup I removed a few unnecessary finalizers.

Our classes rarely handle unmanaged resources directly. The need to implement IDisposable is usually because:

1. The class contains IDIsposable objects that need to be Dispose'd.
2. The class hooks event handlers that will prevent garbage collection.
donw146
 
Posts: 4
Joined: Thu Feb 13, 2014 9:49 pm
Location: Canada

Re: Control.ControlNativeWindow in the finalizer queue

Postby Andreas Suurkuusk » Thu Feb 20, 2014 5:05 pm

Most likely the finalization is much quicker now, and therefore you no longer see the finalized Control.ControlNativeWindow instances. If you wish to see whether the Control.ControlNativeWindow instances are still being finalized, you can add the "Finalized instances" band to the types list (using the command View->Layout->Column chooser).
Best regards,

Andreas Suurkuusk
SciTech Software AB
Andreas Suurkuusk
 
Posts: 964
Joined: Wed Mar 02, 2005 7:53 pm
Location: Sweden


Return to Known Memory Issues

Who is online

Users browsing this forum: No registered users and 1 guest

SciTech Software logo

© Copyright 2001-2016. SciTech Software AB
All rights reserved.


SciTech Software AB
Kartvägen 21
SE-175 46 Järfälla
Sweden


E-mail: mail@scitech.se

Telephone: +46-706868081

cron