optimizing-wpf-memory

WPF Memory Optimization

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "optimizing-wpf-memory" with this command: npx skills add christian289/dotnet-with-claudecode/christian289-dotnet-with-claudecode-optimizing-wpf-memory

WPF Memory Optimization

  1. Freezable Pattern

Why Freeze?

Benefit Description

Thread-safe Can be used across threads

No change tracking Reduces overhead

Renderer optimization Better GPU utilization

Basic Usage

// Always freeze static resources var brush = new SolidColorBrush(Colors.Red); brush.Freeze();

var pen = new Pen(Brushes.Black, 1); pen.Freeze();

XAML Freeze

<Window xmlns:po="http://schemas.microsoft.com/winfx/2006/xaml/presentation/options" mc:Ignorable="po"> <Window.Resources> <SolidColorBrush x:Key="FrozenBrush" Color="Red" po:Freeze="True"/> </Window.Resources> </Window>

When Freeze Fails

if (brush.CanFreeze) brush.Freeze(); else // Has bindings or animations - cannot freeze

Modifying Frozen Objects

var clone = frozenBrush.Clone(); // Creates unfrozen copy clone.Color = Colors.Blue; clone.Freeze(); // Freeze again if needed

  1. Common Memory Leaks

Event Handler Leaks

// ❌ LEAK: Static event holds reference SomeStaticClass.StaticEvent += OnEvent;

// ✅ FIX: Unsubscribe in Unloaded Unloaded += (s, e) => SomeStaticClass.StaticEvent -= OnEvent;

CompositionTarget.Rendering Leak

// ❌ LEAK: Never unsubscribed CompositionTarget.Rendering += OnRendering;

// ✅ FIX: Always unsubscribe Loaded += (s, e) => CompositionTarget.Rendering += OnRendering; Unloaded += (s, e) => CompositionTarget.Rendering -= OnRendering;

Binding Without INotifyPropertyChanged

// ❌ LEAK: PropertyDescriptor retained public string Name { get; set; } // No INPC

// ✅ FIX: Implement INPC public string Name { get => _name; set { _name = value; OnPropertyChanged(); } }

DispatcherTimer Leak

// ❌ LEAK: Timer keeps running _timer = new DispatcherTimer(); _timer.Tick += OnTick; _timer.Start();

// ✅ FIX: Stop and cleanup Unloaded += (s, e) => { _timer.Stop(); _timer.Tick -= OnTick; };

Image Resource Leak

// ❌ LEAK: Stream kept open var bitmap = new BitmapImage(new Uri(path));

// ✅ FIX: Load immediately and release stream var bitmap = new BitmapImage(); bitmap.BeginInit(); bitmap.CacheOption = BitmapCacheOption.OnLoad; bitmap.UriSource = new Uri(path); bitmap.EndInit(); bitmap.Freeze();

  1. Diagnostic Checklist

Code Review Points

  • All static event subscriptions have unsubscribe logic

  • CompositionTarget.Rendering unsubscribed in Unloaded

  • DispatcherTimer stopped in Unloaded

  • ViewModels implement INotifyPropertyChanged

  • Images use BitmapCacheOption.OnLoad

  • Static resources are Frozen

Diagnostic Tools

Tool Purpose

VS Diagnostic Tools Real-time memory snapshots

dotMemory Detailed retention paths

PerfView GC and allocation analysis

Memory Monitor

public static class MemoryMonitor { public static void LogMemory(string context) { GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect();

    var mem = GC.GetTotalMemory(true) / 1024.0 / 1024.0;
    Debug.WriteLine($"[{context}] Memory: {mem:F2} MB");
}

}

  1. Resource Factory Pattern

public static class FrozenResources { public static SolidColorBrush CreateBrush(Color color) { var brush = new SolidColorBrush(color); brush.Freeze(); return brush; }

public static Pen CreatePen(Color color, double thickness)
{
    var pen = new Pen(CreateBrush(color), thickness);
    pen.Freeze();
    return pen;
}

}

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

converting-html-css-to-wpf-xaml

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

publishing-wpf-apps

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

using-xaml-property-element-syntax

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

managing-styles-resourcedictionary

No summary provided by upstream source.

Repository SourceNeeds Review