Apparent memory leak with recursive QTimer::singleshot.
-
I've tracked down a memory leak to a repeating singleshot timer. I'm not sure if the cause lies in Qt, is my own oversight, or something else, but I can reproduce it with a minimal example. I'm having this problem on a Windows 7 machine using Qt 6.0.0 and haven't been able to find anything addressing it online. So, the steps to reproduce are:
- Create a new Qt Widgets app.
- Create a function slot on MainWindow. Mine is called "executionLoop()"
- Call the function slot from the MainWindow constructor.
- Put the following code in the function:
void MainWindow::executionLoop() { QTimer::singleShot(1, Qt::PreciseTimer, this, SLOT(executionLoop())); }
The program will slowly but surely eat more RAM without ever freeing it. Unless I'm missing something, a singleshot timer should fire once and deallocate afterwards. Since the function is called once from outside and only recursively after that, there should only exist one singleshot timer at any given time. Anyone know what's going on?
Clarification in case it wasn't obvious: this is in C++.
-
Check with address sanitizer.
How do you check RAM usage? If you are using System Monitor, it's very possible that each QTimer instance allocates new portion of RAM because you have free RAM available. Operating Systems often do it - the old instances are freed, but still the memory continues being "reserved" for your application. Only when there is not much RAM available, OS will start reusing old memory addresses.
I'm not saying there is no leak here, I'm saying there maybe isn't one.
-
Please provide a minimal compilable example so we can reproduce the issue.
-
@Christian-Ehrlicher I'm not 100% sure this is a bug yet, but I made a bug report here already with a test project: https://bugreports.qt.io/browse/QTBUG-92912
I've been letting it run for a while now and according to Task Manager, it's slowly climbed to using 2.3 GB of RAM.
-
Thx, but don't lease attach the binaries - they're not needed at a 8MB reproducer just scares the reader.
-
@Christian-Ehrlicher Okay, my mistake. So, after letting the program run for about 24 hours straight. It reached about 3.5 GB used. I opened another application with high memory use that pushed the physical RAM usage to 98%. At this point, the application DID release about 2 GB and is now sitting at around 1.3 GB used, but it also caused the system to become unresponsive for some time, which was probably from the virtual memory swapping. Despite that, it seems like unacceptable and unexpected behavior for an application that simply runs a timer repeatedly to eventually take that much RAM.