15
votes

I'm using .NET 4.5 on Windows 7, and might find a memory leak.
I have a TextBlock (not TextBox - it's not the Undo problem), which changes its value every second (CPU usage, time, etc...).
Using .NET Memory Profiler (and by simply watching task manager) I noticed the memory keeps on growing. To be more accurate, I see more and more live instances of UnmanagedMemoryStream (I tried GC.Collect() which obviously didn't do anything).

After some tests, I've found out that this problem appears only when I'm setting the TextBlock font to a resource font as follows:

<Style TargetType="{x:Type TextBlock}">
    <Setter Property="Control.Foreground" Value="#CCCCCC"/>
    <Setter Property="FontFamily" Value="pack://application:,,,/MyUIControls;component/./Fonts/#Noto Sans"/>
</Style>

I tried updating the Text property directly from code or via Binding, it behaves the same for both ways.

Bottom line:
When the FontFamily is set, instances of UnmanagedMemoryStream keep on coming (forever) each time I'm updating the text. When I don't (set the FontFamily property), memory is stable.
(BTW, it happens when I use Label instead of TextBlock as well)

It looks like a memory leak but I couldn't find any reference about it.
Any suggestions of how can it be solved?

1
I know that it's an old question, but out of curiosity - have you tried to put the font resource into the app resource dictionary? Does it leak as well? <FontFamily x:Key="AppFont">pack://application:,,,/MyUIControls;component/./Fonts/#Noto Sans</FontFamily> and then use it <Setter Property="FontFamily" Value="{StaticResource AppFont}" />Endrju
As @Endrju 's suggestion essentially creates a singleton of that font family object hold in a resource dict, it sould solve the memory issue.Robetto

1 Answers

18
votes

A FontFamily leaks UnmanagedMemoryStreams when it is used if it was sourced from an embedded resource or a relative path. When the FontFamily is sourced from a system font or absolute path, it does not leak.

You can look here and download the project that reproduces the problem.

Workaround: For Resource fonts: save fonts into a temporary folder and use the absolute path to the stored font. For relative path fonts: resolve and use the absolute path instead.