2

I just started to work with Wt, and it seems that memory used by the program is constantly increasing (as shown by System Monitor on Ubuntu). This happens in many different contexts, event though the destructors are invoked.

My guess is that Wt is keeping copies of some data, and I wonder if there is a way to force Wt to free that memory.

The simplest example (appended below) is an app that creates/deletes a WText with a huge string. Calling create/delete slots multiple times causes a constant memory increase. For fun, I added two buttons that call those slots from the browser.

Here is the code

#include <Wt/WApplication.h>
#include <Wt/WBreak.h>
#include <Wt/WContainerWidget.h>
#include <Wt/WPushButton.h>
#include <Wt/WText.h>

using namespace Wt;
class App: public Wt::WApplication
{
public:
    App(const Wt::WEnvironment& env);
private:
    static std::string  createHugeString();

    void createWText()
    { if(!m_widgetPtr)
        m_widgetPtr=this->root()->addNew<Wt::WText>(createHugeString());
    }

    void deleteWText()
    {  if(m_widgetPtr)
         auto uptr=root()->removeChild(m_widgetPtr);
         // will be deleted by unique_ptr dtor
       m_widgetPtr=nullptr;
    }

    Wt::WWidget *m_widgetPtr = nullptr;
};


App::App(const Wt::WEnvironment& env)
    :Wt::WApplication(env)
{
    auto *createTextButtonPtr = root()->addNew<WPushButton>("Create WText");
    auto *delTextButtonPtr = root()->addNew<WPushButton>("Delete WText");
    root()->addNew<WBreak>();

    createTextButtonPtr->clicked().connect(this,&App::createWText);
    delTextButtonPtr->clicked().connect(this,&App::deleteWText);
} //constructor


std::string App::createHugeString()
{
    std::string htmlStr;
    for(std::size_t i =0; i!=20000000/4; ++i){
        htmlStr += "a b ";
    }
    return htmlStr;
}


int main()
{
    char* argv[]= {"progname", "--docroot", "." ,
                   "--http-address", "0.0.0.0",
                   "--http-port", "8080"
                   };
    int argc = sizeof(argv)/sizeof(*argv);

    return Wt::WRun(argc, argv, [](const Wt::WEnvironment& env) {
      return std::make_unique<App>(env);
    });
}
Adrian
  • 987
  • 5
  • 13
  • 1
    Do you ever free the object pointed to by `m_widgetPtr`? It just looks like you remove it from some list of widgets. If not, that could be a memory leak. You should probably run a tool designed to detect memory leaks - such as [valgrind](https://valgrind.org/). – fredrik Apr 09 '20 at 15:18
  • Compiling with `-fsanitize=address` is several times faster than valgrind (and more accurate), but occasionally tricky to set up. – o11c Apr 09 '20 at 15:19
  • There is a comment in the code `// will be deleted by unique_ptr dtor` but there are no `unique_ptr` instances anywhere. – dewaffled Apr 09 '20 at 15:20
  • @fredrik root()->removeChild() returns temporary unique_ptr that deletes WText ptr – Adrian Apr 09 '20 at 15:28
  • @fredrik it's from a `std::vector>` – Caleth Apr 09 '20 at 16:15

1 Answers1

1

createHugeString() would probably increase memory usage, even without leak: you fragment the memory.

reserve correct dimension for htmlStr should avoid some fragmentations.

Jarod42
  • 203,559
  • 14
  • 181
  • 302
  • I did that, and even replaced createHugeString() by reference to (properly reserved) string with static storage duration. But the problem stil remains. – Adrian Apr 09 '20 at 15:47
  • System Monitor is not really the right tool for memory leak. 2 better alternatives are already be suggested in comments. And as I state, we might have increasing consumption without memory leak. – Jarod42 Apr 09 '20 at 15:52