Linux: Force release of unused memory

Apparently, glibc uses an overly aggressive caching strategy, causing
Creator to accumulate an unreasonable amount of resident memory over
time.
We deal with this by manually forcing glibc to free unused memory once a
minute, provided the application is actually in use.

Fixes: QTCREATORBUG-22832
Change-Id: I300eafd8714eb7e49774129758998db32ca1a1de
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
Christian Kandeler
2020-05-04 11:58:50 +02:00
parent 6683dc1063
commit b9e79f7852

View File

@@ -69,6 +69,10 @@
#include <qtsystemexceptionhandler.h> #include <qtsystemexceptionhandler.h>
#endif #endif
#ifdef Q_OS_LINUX
#include <malloc.h>
#endif
using namespace ExtensionSystem; using namespace ExtensionSystem;
enum { OptionIndent = 4, DescriptionIndent = 34 }; enum { OptionIndent = 4, DescriptionIndent = 34 };
@@ -704,5 +708,32 @@ int main(int argc, char **argv)
// shutdown plugin manager on the exit // shutdown plugin manager on the exit
QObject::connect(&app, &QCoreApplication::aboutToQuit, &pluginManager, &PluginManager::shutdown); QObject::connect(&app, &QCoreApplication::aboutToQuit, &pluginManager, &PluginManager::shutdown);
#ifdef Q_OS_LINUX
class MemoryTrimmer : public QObject
{
public:
MemoryTrimmer()
{
m_trimTimer.setSingleShot(true);
m_trimTimer.setInterval(60000);
// glibc may not actually free memory in free().
connect(&m_trimTimer, &QTimer::timeout, this, [] { malloc_trim(0); });
}
bool eventFilter(QObject *, QEvent *e) override
{
if ((e->type() == QEvent::MouseButtonPress || e->type() == QEvent::KeyPress)
&& !m_trimTimer.isActive()) {
m_trimTimer.start();
}
return false;
}
QTimer m_trimTimer;
};
MemoryTrimmer trimmer;
app.installEventFilter(&trimmer);
#endif
return restarter.restartOrExit(app.exec()); return restarter.restartOrExit(app.exec());
} }