Skip to content

Memory Leak in TextShaper cache #101

@jack775544

Description

@jack775544

Very similar issue to #35

Using the following test program:

using SkiaSharp;
using Topten.RichTextKit;

var mapper = new TestFontMapper();

for (var i = 0; i < 1000; i++)
{
    var text = new TextBlock
    {
        FontMapper = mapper
    };

    text.AddText("This is a test of RichTextKit memory management.", new Style
    {
        FontSize = 12,
        FontFamily = "Testing",
    });

    text.Layout();
}

Console.WriteLine("Done");

public class TestFontMapper : FontMapper
{
    public override SKTypeface TypefaceFromStyle(IStyle style, bool ignoreFontVariants)
    {
        return SKTypeface.FromFile("OpenSans-Regular.ttf");
    }
}

If I breakpoint on the Console.WriteLine and inspect the value of Topten.RichTextKit.TextShaper._shapers in the debugger, there is 1000 entries.

From my understanding this is since each call to SKTypeface.FromFile in the custom font mapper will return a new object every time. When TextShaper.ForTypeface is called as a part of the layout process, the new object will bust the cache since the new typeface will never be the same object as an existing typeface.

Like in #35, I was able to fix this in my own application by caching the SKTypefaces that I create.

I believe a more proper fix for this issue is to use a combination of font name, slant, weight and width as the cache key instead of the class. I have made this change in a local copy of the repo and it does alleviate the issue. Happy to push it up as a PR if that seems like a valid fix.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions