question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Control._reflectParent is not updated when Parent changes (memory leak)

See original GitHub issue

.NET version

.NET 7.0.5 (latest public release)

Did it work in .NET Framework?

No

Did it work in any of the earlier releases of .NET Core or .NET 5+?

I don’t think this is a regression, it was probably always like this. I’ve never needed to worry about this in the past – my use of Controls did not include reparenting until now.

Issue description

The Control._reflectParent field points to a control’s parent control. It is updated by calling set_ReflectParent via UpdateReflectParent(), which is called by CreateHandle(), Dispose(bool), and OnHandleDestroyed(EventArgs).

Notably absent from that list is OnParentChanged() (or any method to that effect). This means that _reflectParent is not set to null when a control is removed from its parent, nor is it updated when the control is added to a new parent.

Here is the ILSpy analysis tree for _reflectParent :

image

This results in a memory leak if a control is re-used, which is something I’m doing in Paint.NET to implement a large memory use optimization. This optimization depends on a control’s Handle not being recreated during a reparenting operation (which does work fine).

In SciTech Memory Profile we can see this clearly. In this case, the CanvasControlImpl (child) has been removed from the CanvasControl (parent), but it (child) still has a reference to it (parent) whether it (child) has been reparented yet or not. The yellow exclamation mark indicates that CanvasControl is disposed.

image

I don’t know if there are other behavioral bugs that result from this – ReflectParent only seems to be read by OnParentHandleRecreated().

Steps to reproduce

  1. Create two Controls, c1 and c2
  2. Add c1 to a Form
  3. Add c2 as a child of c1
  4. Show the form
  5. Remove c2 from c1
  6. Inspect c2._reflectParent. It should be null, but it still references c1.

Issue Analytics

  • State:closed
  • Created 4 months ago
  • Reactions:2
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
JeremyKuhnecommented, Jun 1, 2023

@Nora-Zhou01 there really isn’t much of value you can do to repro- I added a unit test that does this.

Apparently, I didn’t mark my PR correctly. I’m closing this now.

0reactions
rickbrewcommented, Jun 1, 2023

@rickbrew We have made some attempts but we don’t seem to find the most accurate sample app, could you please provide the sample project, thanks in advance.

I’m not sure I understand … @JeremyKuhne landed a fix for this in #9159. What is it exactly that you need from me? Like a minimal repro? As in, a Visual Studio project you can run that will reproduce the issue?

Read more comments on GitHub >

github_iconTop Results From Across the Web

Control._reflectParent is not updated when Parent changes ...
NET UI framework for building Windows desktop applications. - Control._reflectParent is not updated when Parent changes (memory leak) · dotnet/winforms@0266ee3.
Read more >
Trying to replace Controls.Clear() to avoid memory leak ...
And I get the following error: at Application.Run(new Form1()); System.ObjectDisposedException was unhandled Cannot access a disposed object.
Read more >
BUG: Changing parent of a model/part many times LEAKS ...
The issue is: the more you change the parent of a model/part, the longer it takes next time to change its parent and...
Read more >
Fighting Common WPF Memory Leaks with dotMemory
When we bind to an instance's Name property, the binding target starts listening for property change notifications. If the property is not a ......
Read more >
Reference Cycles Can Leak Memory
Preventing memory leaks entirely is not one of Rust's guarantees, meaning memory leaks are memory safe in Rust. We can see that Rust...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found