How correctly free memory in Qt C++
-
I store thousand of
QImage *
andQByteArray*
in aQQueue*
. After used I get rid of them usingdelete + nullptr
, but I found out that the memory is never freed and after a while it totally saturates.
This is how I use them:QQueue<QImage / QByteArray *> q; // somewhere in my code data = new QImage / QByteArray q.enqueue(data) //where I use them QImage / QByteArray * data = q.dequeue(); //use data delete data; data = nullptr; // I know, is useless!
I thought my memory stay the same or grows at a low rate instead it always grows even after calling delete and after a while it uses all available memory (I reached something like 6/7GB).
I don't create any pointer with new, so in my test the memory grows only due to that QQueue.
I'm missing something in Qt like a preservation of allocated memory?
Should I use free instead of delete? -
Christian Ehrlicher Lifetime Qt Championreplied to TheEnigmist on last edited by Christian Ehrlicher
@TheEnigmist said in How correctly free memory in Qt C++:
I thought my memory stay the same or grows at a low rate instead it always grows even after calling delete and after a while it uses all available memory (I reached something like 6/7GB).
Then you have a memory leak somewhere else.
Don't allocate QImage/QByteArray on the heap - it's implicitly shared so no need for it --> QQueue<QImage> - then you don't have to worry about the deleting something here.
-
@Christian-Ehrlicher
Sure I've some memory leak somewhere else, but I tried the same code without all that QImage / QByteArray and it grow really slow (some MB each iteration)Btw thanks for the link, I will look at it and change my logic to see if I mitigate this huge problem.
-
When your queue grows then you need more memory - make sure you worker is faster than the one who fills the queue or limit the queue size.
-
@TheEnigmist do you run your code continuously in an infinite loop? You will have to give control back to your OS eventually, so that it can actually reassign / the memory your application requested previously and is now supposedly freed.
-
@TheEnigmist
In addition to the points others have made above:-
Make absolutely sure you do call
q.dequeue();
for each item before youdelete
it. Otherwise yourq
will keep growing (e.g. verifyq.size()
). -
If by any chance it is the size of an ever-growing
QQueue
that is causing the memory consumption, you could see what happens if you obviate that via e.g.q.reserve(100000)
when you createq
. -
If your
QImage / QByteArray
is "very large" compared to the size of an item (a pointer here) in theQQueue
--- as I imagine is the case --- then you should be able to figure whether it is thenew
ed item versus the extra element in theQQueue
that is causing the memory growth.
-
-
@Christian-Ehrlicher said in How correctly free memory in Qt C++:
When your queue grows then you need more memory - make sure you worker is faster than the one who fills the queue or limit the queue size.
Well actually the thread that enqueue is really faster than dequeue, I'm thinking on limiting enqueue and add more data only when the Queue is near to empty. Can I put a max size of the queue, can't I?
@J-Hilk said in How correctly free memory in Qt C++:
@TheEnigmist do you run your code continuously in an infinite loop? You will have to give control back to your OS eventually, so that it can actually reassign / the memory your application requested previously and is now supposedly freed.
All infinite loops are under threads.
@JonB said in How correctly free memory in Qt C++:
@TheEnigmist
In addition to the points others have made above:- Make absolutely sure you do call
q.dequeue();
for each item before youdelete
it. Otherwise yourq
will keep growing (e.g. verifyq.size()
).
I do like this, actually I put all my item in the queue in little time and dequeue them with another thread. The timeline is something like this:
- Put all the thousands item in the Queue;
- Dequeue all the item one by one and after used it delete it;
- Repeat;
Before point 3 I thought my memory goes back to a normal size.
- If by any chance it is the size of an ever-growing
QQueue
that is causing the memory consumption, you could see what happens if you obviate that via e.g.q.reserve(100000)
when you createq
.
I'm thinking about limiting the enqueue data, something like
reserve(1000)
and whenq.size < 100
enqueue other data up to 1000.- If your
QImage / QByteArray
is "very large" compared to the size of an item (a pointer here) in theQQueue
--- as I imagine is the case --- then you should be able to figure whether it is thenew
ed item versus the extra element in theQQueue
that is causing the memory growth.
I thought pointer was little enough to put in a container, but has figured out by @Christian-Ehrlicher is better avoid pointer with that classes
I need to test a lot of thing to figure out where the problem is! I come back with futher infos!
- Make absolutely sure you do call
-
@TheEnigmist said in How correctly free memory in Qt C++:
Can I put a max size of the queue, can't I?
Since you fill and fetch the queue you can also make sure that there are not more than X elements in there.
-
@Christian-Ehrlicher said in How correctly free memory in Qt C++:
@TheEnigmist said in How correctly free memory in Qt C++:
Can I put a max size of the queue, can't I?
Since you fill and fetch the queue you can also make sure that there are not more than X elements in there.
I will do with this to avoid memory leak for filling too much my Queue.
Btw thx to @Christian-Ehrlicher I found that the solution is so simple. Avoid using pointers with QImage / QByteArray. Now QImage get rid all the memory used while QByteArray has something like 0.5/0.6 MB of data after usage.
I don't know if is something I can control, but I can manage to have this +0.6MB grow rate. -
@TheEnigmist said in How correctly free memory in Qt C++:
I don't know if is something I can control, but I can manage to have this +0.6MB grow rate.
Don't think this comes from the Queue when it doesn't grow indefinitely. It must be from somewhere else.