Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,16 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

## [0.53.1] - 2026-05-14

### Fixed
- **Resource leak: NetworkSharedState** — dispose SKTypeface on LegendTextPaint
in Dispose() to release unmanaged SkiaSharp memory (LEAK-003).
- **Resource leak: TrayIconService** — dispose icon resource stream after
creating System.Drawing.Icon to prevent stream leak (LEAK-006).
- **Resource leak: MemoryTestService** — dispose Process returned by
Process.Start when launching mdsched.exe (LEAK-007).

## [0.53.0] - 2026-05-13

### Added
Expand Down
2 changes: 1 addition & 1 deletion SysManager/SysManager/Services/MemoryTestService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ public bool ScheduleAtNextBoot()
// mdsched.exe prompts interactively. Use the schedule flag to avoid UI.
// On Win10/11, the easiest way without UI is the "bcdedit" toggle used
// behind the scenes, but safest portable option is to launch mdsched.
Process.Start(new ProcessStartInfo
using var proc = Process.Start(new ProcessStartInfo
{
FileName = "mdsched.exe",
UseShellExecute = true
Expand Down
6 changes: 4 additions & 2 deletions SysManager/SysManager/Services/TrayIconService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,10 @@ public static void HideWindow(Window window)
try
{
var uri = new Uri("pack://application:,,,/Resources/app.ico", UriKind.Absolute);
var stream = Application.GetResourceStream(uri)?.Stream;
return stream != null ? new System.Drawing.Icon(stream) : null;
var streamInfo = Application.GetResourceStream(uri);
if (streamInfo?.Stream == null) return null;
using var stream = streamInfo.Stream;
return new System.Drawing.Icon(stream);
}
catch (System.IO.IOException ex)
{
Expand Down
3 changes: 3 additions & 0 deletions SysManager/SysManager/ViewModels/NetworkSharedState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -450,7 +450,7 @@
Labeler = v => new DateTime((long)v).ToString("HH:mm:ss"),
TextSize = 12,
NamePaint = new SolidColorPaint(SKColor.Parse("A3ADBF")),
LabelsPaint = new SolidColorPaint(SKColor.Parse("E6E9EE")) { FontFamily = "Segoe UI" },

Check warning on line 453 in SysManager/SysManager/ViewModels/NetworkSharedState.cs

View workflow job for this annotation

GitHub Actions / Analyze (csharp)

'SkiaPaint.FontFamily' is obsolete: 'Use the SKTypeface property and assign it to SKTypeface.FromFamilyName(fontFamily, fontStyle)'

Check warning on line 453 in SysManager/SysManager/ViewModels/NetworkSharedState.cs

View workflow job for this annotation

GitHub Actions / Analyze (csharp)

'SkiaPaint.FontFamily' is obsolete: 'Use the SKTypeface property and assign it to SKTypeface.FromFamilyName(fontFamily, fontStyle)'

Check warning on line 453 in SysManager/SysManager/ViewModels/NetworkSharedState.cs

View workflow job for this annotation

GitHub Actions / Analyze (csharp)

'SkiaPaint.FontFamily' is obsolete: 'Use the SKTypeface property and assign it to SKTypeface.FromFamilyName(fontFamily, fontStyle)'

Check warning on line 453 in SysManager/SysManager/ViewModels/NetworkSharedState.cs

View workflow job for this annotation

GitHub Actions / Build & unit tests

'SkiaPaint.FontFamily' is obsolete: 'Use the SKTypeface property and assign it to SKTypeface.FromFamilyName(fontFamily, fontStyle)'

Check warning on line 453 in SysManager/SysManager/ViewModels/NetworkSharedState.cs

View workflow job for this annotation

GitHub Actions / Build & unit tests

'SkiaPaint.FontFamily' is obsolete: 'Use the SKTypeface property and assign it to SKTypeface.FromFamilyName(fontFamily, fontStyle)'

Check warning on line 453 in SysManager/SysManager/ViewModels/NetworkSharedState.cs

View workflow job for this annotation

GitHub Actions / Build & unit tests

'SkiaPaint.FontFamily' is obsolete: 'Use the SKTypeface property and assign it to SKTypeface.FromFamilyName(fontFamily, fontStyle)'

Check warning on line 453 in SysManager/SysManager/ViewModels/NetworkSharedState.cs

View workflow job for this annotation

GitHub Actions / UI automation tests

'SkiaPaint.FontFamily' is obsolete: 'Use the SKTypeface property and assign it to SKTypeface.FromFamilyName(fontFamily, fontStyle)'

Check warning on line 453 in SysManager/SysManager/ViewModels/NetworkSharedState.cs

View workflow job for this annotation

GitHub Actions / UI automation tests

'SkiaPaint.FontFamily' is obsolete: 'Use the SKTypeface property and assign it to SKTypeface.FromFamilyName(fontFamily, fontStyle)'

Check warning on line 453 in SysManager/SysManager/ViewModels/NetworkSharedState.cs

View workflow job for this annotation

GitHub Actions / UI automation tests

'SkiaPaint.FontFamily' is obsolete: 'Use the SKTypeface property and assign it to SKTypeface.FromFamilyName(fontFamily, fontStyle)'
SeparatorsPaint = new SolidColorPaint(SKColor.Parse("2A3244").WithAlpha(80))
};

Expand All @@ -459,8 +459,8 @@
Name = name,
MinLimit = 0,
TextSize = 13,
NamePaint = new SolidColorPaint(SKColor.Parse("E6E9EE")) { FontFamily = "Segoe UI" },

Check warning on line 462 in SysManager/SysManager/ViewModels/NetworkSharedState.cs

View workflow job for this annotation

GitHub Actions / Analyze (csharp)

'SkiaPaint.FontFamily' is obsolete: 'Use the SKTypeface property and assign it to SKTypeface.FromFamilyName(fontFamily, fontStyle)'

Check warning on line 462 in SysManager/SysManager/ViewModels/NetworkSharedState.cs

View workflow job for this annotation

GitHub Actions / Analyze (csharp)

'SkiaPaint.FontFamily' is obsolete: 'Use the SKTypeface property and assign it to SKTypeface.FromFamilyName(fontFamily, fontStyle)'

Check warning on line 462 in SysManager/SysManager/ViewModels/NetworkSharedState.cs

View workflow job for this annotation

GitHub Actions / Analyze (csharp)

'SkiaPaint.FontFamily' is obsolete: 'Use the SKTypeface property and assign it to SKTypeface.FromFamilyName(fontFamily, fontStyle)'

Check warning on line 462 in SysManager/SysManager/ViewModels/NetworkSharedState.cs

View workflow job for this annotation

GitHub Actions / Build & unit tests

'SkiaPaint.FontFamily' is obsolete: 'Use the SKTypeface property and assign it to SKTypeface.FromFamilyName(fontFamily, fontStyle)'

Check warning on line 462 in SysManager/SysManager/ViewModels/NetworkSharedState.cs

View workflow job for this annotation

GitHub Actions / Build & unit tests

'SkiaPaint.FontFamily' is obsolete: 'Use the SKTypeface property and assign it to SKTypeface.FromFamilyName(fontFamily, fontStyle)'

Check warning on line 462 in SysManager/SysManager/ViewModels/NetworkSharedState.cs

View workflow job for this annotation

GitHub Actions / Build & unit tests

'SkiaPaint.FontFamily' is obsolete: 'Use the SKTypeface property and assign it to SKTypeface.FromFamilyName(fontFamily, fontStyle)'

Check warning on line 462 in SysManager/SysManager/ViewModels/NetworkSharedState.cs

View workflow job for this annotation

GitHub Actions / UI automation tests

'SkiaPaint.FontFamily' is obsolete: 'Use the SKTypeface property and assign it to SKTypeface.FromFamilyName(fontFamily, fontStyle)'

Check warning on line 462 in SysManager/SysManager/ViewModels/NetworkSharedState.cs

View workflow job for this annotation

GitHub Actions / UI automation tests

'SkiaPaint.FontFamily' is obsolete: 'Use the SKTypeface property and assign it to SKTypeface.FromFamilyName(fontFamily, fontStyle)'

Check warning on line 462 in SysManager/SysManager/ViewModels/NetworkSharedState.cs

View workflow job for this annotation

GitHub Actions / UI automation tests

'SkiaPaint.FontFamily' is obsolete: 'Use the SKTypeface property and assign it to SKTypeface.FromFamilyName(fontFamily, fontStyle)'
LabelsPaint = new SolidColorPaint(SKColor.Parse("E6E9EE")) { FontFamily = "Segoe UI" },

Check warning on line 463 in SysManager/SysManager/ViewModels/NetworkSharedState.cs

View workflow job for this annotation

GitHub Actions / Analyze (csharp)

'SkiaPaint.FontFamily' is obsolete: 'Use the SKTypeface property and assign it to SKTypeface.FromFamilyName(fontFamily, fontStyle)'

Check warning on line 463 in SysManager/SysManager/ViewModels/NetworkSharedState.cs

View workflow job for this annotation

GitHub Actions / Analyze (csharp)

'SkiaPaint.FontFamily' is obsolete: 'Use the SKTypeface property and assign it to SKTypeface.FromFamilyName(fontFamily, fontStyle)'

Check warning on line 463 in SysManager/SysManager/ViewModels/NetworkSharedState.cs

View workflow job for this annotation

GitHub Actions / Build & unit tests

'SkiaPaint.FontFamily' is obsolete: 'Use the SKTypeface property and assign it to SKTypeface.FromFamilyName(fontFamily, fontStyle)'

Check warning on line 463 in SysManager/SysManager/ViewModels/NetworkSharedState.cs

View workflow job for this annotation

GitHub Actions / Build & unit tests

'SkiaPaint.FontFamily' is obsolete: 'Use the SKTypeface property and assign it to SKTypeface.FromFamilyName(fontFamily, fontStyle)'

Check warning on line 463 in SysManager/SysManager/ViewModels/NetworkSharedState.cs

View workflow job for this annotation

GitHub Actions / UI automation tests

'SkiaPaint.FontFamily' is obsolete: 'Use the SKTypeface property and assign it to SKTypeface.FromFamilyName(fontFamily, fontStyle)'

Check warning on line 463 in SysManager/SysManager/ViewModels/NetworkSharedState.cs

View workflow job for this annotation

GitHub Actions / UI automation tests

'SkiaPaint.FontFamily' is obsolete: 'Use the SKTypeface property and assign it to SKTypeface.FromFamilyName(fontFamily, fontStyle)'
SeparatorsPaint = new SolidColorPaint(SKColor.Parse("2A3244").WithAlpha(80)) { StrokeThickness = 1 },
Labeler = v => $"{v:F0} ms",
NameTextSize = 14,
Expand All @@ -474,7 +474,7 @@
MinStep = 1,
TextSize = 12,
NamePaint = new SolidColorPaint(SKColor.Parse("A3ADBF")),
LabelsPaint = new SolidColorPaint(SKColor.Parse("E6E9EE")) { FontFamily = "Segoe UI" },

Check warning on line 477 in SysManager/SysManager/ViewModels/NetworkSharedState.cs

View workflow job for this annotation

GitHub Actions / Analyze (csharp)

'SkiaPaint.FontFamily' is obsolete: 'Use the SKTypeface property and assign it to SKTypeface.FromFamilyName(fontFamily, fontStyle)'

Check warning on line 477 in SysManager/SysManager/ViewModels/NetworkSharedState.cs

View workflow job for this annotation

GitHub Actions / Analyze (csharp)

'SkiaPaint.FontFamily' is obsolete: 'Use the SKTypeface property and assign it to SKTypeface.FromFamilyName(fontFamily, fontStyle)'

Check warning on line 477 in SysManager/SysManager/ViewModels/NetworkSharedState.cs

View workflow job for this annotation

GitHub Actions / Build & unit tests

'SkiaPaint.FontFamily' is obsolete: 'Use the SKTypeface property and assign it to SKTypeface.FromFamilyName(fontFamily, fontStyle)'

Check warning on line 477 in SysManager/SysManager/ViewModels/NetworkSharedState.cs

View workflow job for this annotation

GitHub Actions / Build & unit tests

'SkiaPaint.FontFamily' is obsolete: 'Use the SKTypeface property and assign it to SKTypeface.FromFamilyName(fontFamily, fontStyle)'

Check warning on line 477 in SysManager/SysManager/ViewModels/NetworkSharedState.cs

View workflow job for this annotation

GitHub Actions / UI automation tests

'SkiaPaint.FontFamily' is obsolete: 'Use the SKTypeface property and assign it to SKTypeface.FromFamilyName(fontFamily, fontStyle)'

Check warning on line 477 in SysManager/SysManager/ViewModels/NetworkSharedState.cs

View workflow job for this annotation

GitHub Actions / UI automation tests

'SkiaPaint.FontFamily' is obsolete: 'Use the SKTypeface property and assign it to SKTypeface.FromFamilyName(fontFamily, fontStyle)'
SeparatorsPaint = new SolidColorPaint(SKColor.Parse("2A3244").WithAlpha(80))
};

Expand All @@ -487,5 +487,8 @@
TraceMonitor.Stop();
TraceMonitor.Dispose();
FlushTimer?.Stop();

// Dispose SKTypeface (unmanaged SkiaSharp memory) — LEAK-003
LegendTextPaint.SKTypeface?.Dispose();
}
Comment on lines +491 to 493

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

find . -name "NetworkSharedState.cs" -type f

Repository: laurentiu021/SystemManager

Length of output: 127


🏁 Script executed:

cat -n ./SysManager/SysManager/ViewModels/NetworkSharedState.cs | head -100

Repository: laurentiu021/SystemManager

Length of output: 4998


🏁 Script executed:

wc -l ./SysManager/SysManager/ViewModels/NetworkSharedState.cs

Repository: laurentiu021/SystemManager

Length of output: 131


🏁 Script executed:

tail -20 ./SysManager/SysManager/ViewModels/NetworkSharedState.cs

Repository: laurentiu021/SystemManager

Length of output: 744


🏁 Script executed:

cat -n ./SysManager/SysManager/ViewModels/NetworkSharedState.cs | sed -n '480,494p'

Repository: laurentiu021/SystemManager

Length of output: 572


🏁 Script executed:

rg "SolidColorPaint" ./SysManager/SysManager/ViewModels/NetworkSharedState.cs -B 2 -A 2

Repository: laurentiu021/SystemManager

Length of output: 2272


🏁 Script executed:

web_search
SKPaint SkiaSharp disposal IDisposable

Repository: laurentiu021/SystemManager

Length of output: 167


🌐 Web query:

SkiaSharp SKPaint Dispose IDisposable memory management

💡 Result:

SKPaint in SkiaSharp implements IDisposable and must be explicitly disposed to release unmanaged native resources promptly, preventing memory leaks especially on resource-constrained devices like mobile.[1][2][3][4] The official documentation states: "Always dispose the object before you release your last reference to the SKPaint. Otherwise, the resources it is using will not be freed until the garbage collector calls the finalizer."[1][5] SKPaint inherits from SKNativeObject, which provides Dispose to release both managed and unmanaged resources, and a protected override Dispose(bool disposing) for the dispose pattern.[1][6][2] Failing to call Dispose delays native resource cleanup until GC finalization, which is non-deterministic and can lead to higher memory usage.[7][8][3] Best practices include: - Use 'using' statements for automatic disposal: using (var paint = new SKPaint) {... }[4] - Cache and reuse SKPaint objects for repeated use (e.g., same stroke color/style), as they are lightweight and do not maintain state like SKCanvas.[6][3][4] Dispose only when no longer needed. - Avoid recreating SKPaint in hot loops; dispose explicitly after caching or when changing properties significantly.[3][4] GC will eventually finalize undisposed objects, but explicit Dispose ensures deterministic cleanup.[9][8][3] Recent issues highlight keeping objects alive during native calls with GC.KeepAlive, but disposal remains essential post-use.[10]

Citations:


🏁 Script executed:

web_search
LiveChartsCore SolidColorPaint Dispose IDisposable

Repository: laurentiu021/SystemManager

Length of output: 174


🌐 Web query:

LiveChartsCore.SkiaSharpView.Painting SolidColorPaint Dispose

💡 Result:

In LiveCharts2, LiveChartsCore.SkiaSharpView.Painting.SolidColorPaint inherits Dispose/Dispose semantics from LiveChartsCore.SkiaSharpView.Painting.SkiaPaint, and you should not treat SolidColorPaint as something you manually dispose in normal UI usage. SolidColorPaint itself is a paint wrapper that sets its color during painting (it updates an internal Skia paint’s Color in OnPaintStarted/Transitionate) and does not create/dispose any Skia shader resources the way gradient paints do [1]. Disposal behavior: - The SolidColorPaint API docs show a Dispose member (inherited from its base) described as “freeing, releasing, or resetting unmanaged resources” [2]. - In the library source, gradient paints override DisposeTask to dispose their internal shader objects (example: LinearGradientPaint disposes _shader in both Transitionate and DisposeTask), which indicates why gradient paints may need disposal if you keep them around for a long time or create many of them [3]. SolidColorPaint does not show such shader disposal logic in its implementation [1]. Practical guidance: - If you pass SolidColorPaint instances as Fill/Stroke in your chart/series, LiveCharts is expected to manage their lifecycle; creating them once and reusing them is typically preferred to repeated allocations. - Only call Dispose if you explicitly created a paint and own its lifecycle outside LiveCharts (e.g., you are dynamically creating many paints and want deterministic cleanup). Otherwise, prefer letting LiveCharts manage them. If you tell me your UI framework (WPF/WinForms/MAUI/etc.) and whether you reuse the same SolidColorPaint instance or create one per render/update, I can give more targeted advice on whether disposing is likely to matter in your scenario.

Citations:


Dispose all owned paint resources, not only the typeface.

Line 492 fixes only part of LEAK-003. NetworkSharedState owns LegendTextPaint, LegendBackgroundPaint, TooltipTextPaint, and TooltipBackgroundPaint (lines 64-67), which should be disposed in Dispose() as well. All four are SolidColorPaint instances created and reused by the class; they should be disposed when the class is disposed.

Proposed fix
     public void Dispose()
     {
         Pinger.SampleReceived -= OnSample;
         TraceMonitor.RouteCompleted -= OnRouteCompleted;
         Pinger.Stop();
         Pinger.Dispose();
         TraceMonitor.Stop();
         TraceMonitor.Dispose();
         FlushTimer?.Stop();

         // Dispose SKTypeface (unmanaged SkiaSharp memory) — LEAK-003
         LegendTextPaint.SKTypeface?.Dispose();
+        LegendTextPaint.Dispose();
+        LegendBackgroundPaint.Dispose();
+        TooltipTextPaint.Dispose();
+        TooltipBackgroundPaint.Dispose();
     }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Dispose SKTypeface (unmanaged SkiaSharp memory) — LEAK-003
LegendTextPaint.SKTypeface?.Dispose();
}
// Dispose SKTypeface (unmanaged SkiaSharp memory) — LEAK-003
LegendTextPaint.SKTypeface?.Dispose();
LegendTextPaint.Dispose();
LegendBackgroundPaint.Dispose();
TooltipTextPaint.Dispose();
TooltipBackgroundPaint.Dispose();
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@SysManager/SysManager/ViewModels/NetworkSharedState.cs` around lines 491 -
493, Dispose the four SolidColorPaint instances owned by NetworkSharedState in
its Dispose() method: call Dispose() (and null them) on LegendTextPaint,
LegendBackgroundPaint, TooltipTextPaint, and TooltipBackgroundPaint in addition
to disposing LegendTextPaint.SKTypeface; ensure Dispose() is idempotent by
null-checking each paint before calling Dispose() so repeated disposals are safe
(update the Dispose method where LegendTextPaint.SKTypeface is currently
disposed).

}
Loading