Memory leakage after creating a new Fl_Tree

10 views
Skip to first unread message

pvr...@btinternet.com

unread,
Jun 11, 2021, 9:00:58 AM6/11/21
to fltk.general
My application has a view based on Fl_Tree which displays a report of the database in the app. Everytime I regenerate the report with different parameters (or a different database) it looks like the the Fl_Tree_Item created by Fl_Tree::add() are not deleted by the Fl_Tree::clear().

I was getting humungous memory leakage problems resulting in my app building up to several hundreds of MB quite quickly and I think eventually causing the app to crash. I was getting spurious crashes that I couldn't resolve. I have resolved the two largest issues, so the Fl_Tree issue is the last remaining one. Every time I regenerate the report memory usage increased by about 1 MB, so it's
not too great an issue, just would like to fix it.

Is it a simple matter starting at the root item and working my way through the tree and deleting all the branches?

I am using fltk-1.4.0 using a snapshot taken April 2020.

Thanks Phil.

Greg Ercolano

unread,
Jun 11, 2021, 10:25:11 AM6/11/21
to fltkg...@googlegroups.com
    Hmm, I'd say make a small program that does something like what you're doing,
    and try to replicate with that. If you can replicate, post the code for the small program
    so we can try to track down the issue.

    Using test/tree I don't see any leaks offhand creating/clearing 20,000 items repeatedly.

    To test, I backgrounded "test/tree", then ran the following to keep an eye on the app's
    memory use:

        while [[ 1 ]]; do sleep 3; ps u --pid <<PID_OF_TREE>>; done

    then in the test/tree app, repeated these two tests while watching the VSZ/RSS values
    of the above command:

        Test just the default tree with 500 items

            1) Hit the button: Test Operations -> "Clear All"
            2) Hit the button: Test Operations -> "Rebuild Tree"
            3) Goto 1

        Test creating/removing the 500 + 20,000 items

            1) Click the "ROOT" item (to highlight it)
            2) Hit the button: Test Operations -> "Add 20,000" (creates an additional 20k items at bottom of tree)
            3) Hit the button: Test Operations -> "Clear All"
            4) Hit the button: Test Operations -> "Rebuild Tree"
            5) Goto 1

    When running the second test, you have to wait for memory to stabilize after the
    first iteration.

    What should happen is the numbers for VSZ/RSS reach a certain value, and then don't
    keep getting bigger on each iteration. If they did get bigger each iteration, that'd be a leak.

    The numbers will NOT get smaller when you hit the "Clear All" button, but should not grow
    each iteration.


Greg Ercolano

unread,
Jun 11, 2021, 11:03:39 AM6/11/21
to fltkg...@googlegroups.com
On 6/11/21 6:00 AM, 'pvr...@btinternet.com' via fltk.general wrote:
Is it a simple matter starting at the root item and working my way through the tree and deleting all the branches?

    You should really just call Fl_Tree::clear() to clear the tree.
    To remove a specific item (and its children, if any), Fl_Tree::remove(item).

    You can try to do it yourself by deleting all the branch items, but I'm pretty sure
    you'd end up with the same results as just doing Fl_Tree::clear(). If there was
    something wrong with the deallocating process, I'd think you'd get the same results.

    Fl_Tree_Item's are around 176 bytes per item on a 64 bit machine, similar in size
    to an Fl_Group. On top of that is the memory for the label() string.

    If you parented FLTK widgets to items using Fl_Tree_Item::widget(),
    to clear /those/, you can call: Fl_Tree::Fl_Group::clear(). So to clear the tree
    and all child FLTK widgets I think you'd need to use:

            tree->clear();
            tree->Fl_Group::clear();


Greg Ercolano

unread,
Jun 11, 2021, 1:39:13 PM6/11/21
to fltkg...@googlegroups.com

On 6/11/21 8:03 AM, Greg Ercolano wrote:

    If you parented FLTK widgets to items using Fl_Tree_Item::widget(),
    to clear /those/, you can call: Fl_Tree::Fl_Group::clear(). So to clear the tree
    and all child FLTK widgets I think you'd need to use:

            tree->clear();
            tree->Fl_Group::clear();


    Actually, I take that back, that advice is bad as that clears Fl_Tree's
    child scrollbar widgets too, which Fl_Tree will not expect.

    To clear all the FLTK child widgets (without clearing the scrollbars),
    Fl_Tree should really provide a method to clear the FLTK child widgets
    along the lines of:

  // Clear all items and FLTK child widgets parented to the tree
  void Fl_Tree::clear_all() {
    clear(); // clears the items

    Fl_Group::remove(_vscroll);
    Fl_Group::remove(_hscroll);

    Fl_Group::clear(); // clears all child fltk widgets except scrollbars
    Fl_Group::add(_vscroll);
    Fl_Group::add(_hscroll);

  }

    You can derive your own class from Fl_Tree and implement that method.
    That's the only way you can access the protected scrollbar members.

    Arguably Fl_Tree::clear() should clear the FLTK child widgets too,
    though there was a desire to allow the items to be cleared separately
    from FLTK widgets, and I don't think that was ever rectified in the API.

    Perhaps it's easier is to simply delete and recreate the Fl_Tree widget,
    as the Fl_Group base class will handle clearing the FLTK children.

    Anyway, all this is /only/ an issue if your app creates FLTK widgets
    and attaches them to the tree with Fl_Tree_Item::widget(w).

Reply all
Reply to author
Forward
0 new messages