Fix critical memory leaks in disposal patterns#16857
Conversation
…nager cleanup Co-authored-by: QilongTang <3942418+QilongTang@users.noreply.github.com>
…l collections and events Co-authored-by: QilongTang <3942418+QilongTang@users.noreply.github.com>
…bustness Co-authored-by: QilongTang <3942418+QilongTang@users.noreply.github.com>
| capturedObject = null; | ||
|
|
||
| // Force garbage collection | ||
| GC.Collect(); |
| // Force garbage collection | ||
| GC.Collect(); | ||
| GC.WaitForPendingFinalizers(); | ||
| GC.Collect(); |
| addNode = null; | ||
|
|
||
| // Force garbage collection | ||
| GC.Collect(); |
| // Force garbage collection | ||
| GC.Collect(); | ||
| GC.WaitForPendingFinalizers(); | ||
| GC.Collect(); |
| capturedObject = null; | ||
|
|
||
| // Force garbage collection | ||
| GC.Collect(); |
| // Force garbage collection | ||
| GC.Collect(); | ||
| GC.WaitForPendingFinalizers(); | ||
| GC.Collect(); |
| // Subscribe a handler that captures the object | ||
| var capturedObject = weakRef.Target; | ||
| manager.RequestLogin += (obj) => { | ||
| var _ = capturedObject; // Capture in closure |
| Assert.Greater(addNode.InPorts.Count, 0, "Node should have input ports"); | ||
| Assert.Greater(addNode.OutPorts.Count, 0, "Node should have output ports"); | ||
|
|
||
| var inPortCount = addNode.InPorts.Count; |
| Assert.Greater(addNode.OutPorts.Count, 0, "Node should have output ports"); | ||
|
|
||
| var inPortCount = addNode.InPorts.Count; | ||
| var outPortCount = addNode.OutPorts.Count; |
|
@copilot The build job failed primarily due to C# compilation errors related to missing namespaces from the test code. The key errors are: error CS0234: The type or namespace name 'Workspaces' does not exist in the namespace 'Dynamo.Tests.Graph' |
Co-authored-by: QilongTang <3942418+QilongTang@users.noreply.github.com>
Fixed in commit 695074d. The test files were using the incorrect namespace |
…null' Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
Co-authored-by: QilongTang <3942418+QilongTang@users.noreply.github.com>
Four critical memory leak patterns identified: undisposed Timer in PulseMaker, uncleared event handlers in IDSDKManager and WorkspaceModel, and uncleared collections in NodeModel. These prevent garbage collection in long-running sessions and workspace lifecycle operations.
Changes
PulseMaker - Timer disposal
Implemented
IDisposablewith thread-safe disposal:IDSDKManager - Event handler cleanup
Clear public events
RequestLoginandLoginStateChangedinDispose()to prevent subscriber references from persisting.NodeModel - Collection cleanup
Clear
InPorts,OutPorts,DismissedAlerts,inputNodes,outputNodesafter disposing child objects:WorkspaceModel - Event and dictionary cleanup
Null 21 event handlers and clear 3 dictionaries (
nodePackageDictionary,localDefinitionsDictionary,externalFilesDictionary) inDispose().ModelBase - Test accessibility
Changed
HasBeenDisposedfromprotectedtoprotected internalto enable test verification viaInternalsVisibleTo.Test Coverage
Added 25 unit tests across disposal scenarios: normal disposal, double-dispose safety, empty collections, thread safety, and connected node cleanup.
Original prompt
💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.