Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[question] Why memory grows when destroying and recreate fonts object? A better approach to change fonts and styles on runtime? #12

Open
moebiussurfing opened this issue Jan 12, 2020 · 3 comments

Comments

@moebiussurfing
Copy link

Hey @armadillu ,

I want to change the added fonts and styles (to the ofxFontStash2::Fonts object) on the fly.
I am trying to use your tip (armadillu/ofxFontStash#29) about destroying the object also with ofxFonStah2:

Otherwise I recommend you keep around different ofxFontStash objects, each setup with the font you need, or just destroy your current fontstash and setup again

ofxFontStash font;
font.setup("myFont.ttf");
font.draw()
....
font = ofxFontStash();
font.setup("myFont2.ttf");
font.draw()

But the memory used by the app is growing very fast (looked into macOS/Activity Monitor). (like from 100MB to 10GB in some minutes)
(I verified that if I do not refresh the fonts, memory do not grows at all.)
This is my refresh method to change the fonts and styles:

void ofxFontAnimator::refreshFontStash2()
{
    ofLogNotice("ofxFontAnimator") << "> refreshFontStash2";

    fonts = ofxFontStash2::Fonts();
    fonts.setup(true);

    //* 1. fonts
    for (int i = 0; i < NUM_STYLES; i++)
    {
        //add font
    }

    //* 2. styles
    for (int i = 0; i < NUM_STYLES; i++)
    {
        //remove style
        //add style
    }
}

The only 'rare' log I can see is:

stb_truetype: can't find kerning tables for this font!

When I try to debug if there are too many fonts or styles added to the object on refresh, I can see that the object has just the 4 expected fonts and styles:

//memory debug
cout << "************************************************" << endl;
auto myFontsID = fonts.getFontIDs();
cout << "fonts : " << ofToString(myFontsID) << endl;
auto myStylesID = fonts.getStyles();
cout << "num styles: " << ofToString(myStylesID.size()) << endl;
cout << "************************************************" << endl;
->

fonts: {font4, font3, font2, font1}
num styles: 4


(I am using ofxFontStash too in the same project)

@moebiussurfing
Copy link
Author

I can see that ofxFontStash has this '= NULL', what seems like a destroyer:

ofxFontStash::ofxFontStash(){
//	stashFontID = 0;
	lineHeight = 1.0f;
	stash = NULL;
	batchDrawing = false;
}

So maybe I need to call this destroy/ 'delete' in some way?

Fonts::~Fonts(){
	#ifdef NANOVG_GL3_IMPLEMENTATION
	ofxfs2_nvgDeleteGL3(ctx);
	#elif defined NANOVG_GL2_IMPLEMENTATION
	ofxfs2_nvgDeleteGL2(ctx);
	#elif defined NANOVG_GLES2_IMPLEMENTATION
	ofxfs2_nvgDeleteGLES2(ctx);
	#endif
}

I tried around this without success:

    fonts.ofxFontStash2::~Fonts();
    //delete fonts;
    //fonts.~Fonts();
    //fonts = ofxFontStash2::~Fonts();

Any idea of how can handle this?

@armadillu
Copy link
Owner

Note that for Fontstash2, a single object can hold N fonts and styles, so you should be ok creating a single object only and adding multiple fonts to it. ofxFontStash can do that but its not so ready/built with that mindset, so I usually create on object per font.

Now, if your styles change over time as the app is running, you will need to load fonts on the fly. Do you now know the styles you will need before the app is launch? Loading fonts is also quite expensive and will likely make your framerate drop. If possible, I would try to pre-load all the styles in setup.

As for memory growing quickly, it likely means there's a leak on the ofxFontstash2 destructor, and I should have a look. Because of the nature of fonts inside interactive apps, I never had to destroy ofxFontStash2 objects directly so the destructor is likely untested, and it may indeed be leaking.

About your tests on forcing a memory release, you shouldn't have to force a destructor call, or ever call directly a destructor. When you do ...

fonts = ofxFontStash2::Fonts();

... the destructor for "fonts" (ofxFontStash2::~Fonts()) is executed. It should cleanup all the resources allocated when constructing the object. If it doesn't, a memory leak occurs, and this is likely what's happening.

For ofxFontStash2 I would recommend you don't delete the ofxFontStash2::Fonts object though, you should just add new fonts to the same object as you need them. Creating and destroying the nvg context is probably an expensive operation. For your case I see there's no way to remove fonts once added (sorry, ofxFontStash2 is quite unfinished) so you could look into implementing one.

about the stb_truetype: can't find kerning tables for this font! I believe is from ofxFontstash and you can ignore it, it just indicates that a particular ttf font doesn't have kerning info.

@moebiussurfing
Copy link
Author

moebiussurfing commented Jan 12, 2020

Thanks a lot for your detailed reply.

I'll look deeper into,
but nevermind about it, sorry, now I disabled the recall of the constructor and the fonts/styles rebuilds in runtime, and I see that memory grows by another cause... So my problem could be in another place.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants