Qt's QTextEdit has big memory leak problem
-
In my object, I display the log file in a QTextEdit widget. Then I find the program consumption hundres MB of memory even the log file size is small . And the memory is not released when its content is cleared.
Then I write a small demo in the QtCreator with Qt5.12.x , just put a QTextEdit widget on it. call the append function to inject QString in it , the problem recurr, even I delete the QTextEdit widget.
MainWindow::MainWindow(QWidget *parent)
{QPushButton *btn1 = new QPushButton(this) ; QPushButton *btn2 = new QPushButton(this) ; txtEdit = new QTextEdit(this) ; QHBoxLayout *layout = new QHBoxLayout ; layout->addWidget( btn1 ) ; layout->addWidget( btn2 ) ; layout->addWidget(txtEdit ) ; QWidget *widget = new QWidget; widget->setLayout(layout); setCentralWidget(widget); connect( btn1 , SIGNAL( clicked( ) ) , this , SLOT( setdata( ) ) ) ; connect( btn2 , SIGNAL( clicked( ) ) , this , SLOT( cleardata( ) ) ) ;}
void MainWindow::setdata( )
{for ( int ii = 0 ; ii < 50 ; ii++ ) { for ( int i = 0 ; i < 500 ; i++ ) { QString str ; for ( int j = 0 ; j < 100 ; j++ ) { str = str+ QString::number( j ) ; } txtEdit->append( str ) ; } }}
void MainWindow::cleardata( )
{txtEdit->clear() ; //txtEdit->close( ) ; //delete txtEdit ;}
-
There is no leak, QTextEdit allows undo/redo operations so the previous stuff must be saved somewhere - see also https://bugreports.qt.io/browse/QTBUG-72123 and https://doc.qt.io/qt-5/qtextedit.html#undoRedoEnabled-prop
-
Sorry , I don't understand what 'undoRedoEnabled ' means ,can I resolve this memory problem by setting it ?
can you explain it more ? Thanks
-
Sorry , I don't understand what 'undoRedoEnabled ' means ,can I resolve this memory problem by setting it ?
can you explain it more ? Thanks
@cyberpunker
Yes, put intxtEdit->setUndoRedoEnabled(false)when you create it and see if it improves.QTextEditby default allows undo (Ctrl+Z)/redo. It has to save the old or new contents every time there is a change to permit that, and that undo history takes up memory. Your code does thousands (2.5 million actually) of modifications to the text, so loads to save for undoing.Disabling the undo/redo feature will mean it does not use that memory.
-
@cyberpunker said in Qt's QTextEdit has big memory leak problem:
Then I find the program consumption hundres MB of memory
How are you measuring this? It may just be that you are seeing erroneous numbers. Qt has some large shared libraries that are mapped into your rpocess address space, but not "really" consuming any physical memory.
-
@cyberpunker said in Qt's QTextEdit has big memory leak problem:
Then I find the program consumption hundres MB of memory
How are you measuring this? It may just be that you are seeing erroneous numbers. Qt has some large shared libraries that are mapped into your rpocess address space, but not "really" consuming any physical memory.
@wrosecrans
I call setUndoRedoEnabled(false) just after construction , then it still can not return all the memory when called clear() . So ,there is no improvment.
I do this on a debian, and I see its status in the task manager. -
@wrosecrans
I call setUndoRedoEnabled(false) just after construction , then it still can not return all the memory when called clear() . So ,there is no improvment.
I do this on a debian, and I see its status in the task manager.@cyberpunker
Well, it makes sense to me that disabling the undo buffer should save a lot of memory in the case of what your code does. But you say not.You cannot assume that memory consumed by a C++/Qt program will be returned to the operating system on freeing variables. It would not be unexpected that this memory is returned to the pool of available memory to be reused by your program, but not deallocated from your program back to the OS. That's not how memory deallocation typically works.
What you should test is:
- Press button to call
setdata()once. - Press button to call
cleardata()once. Preferably have that actually delete and recreatetextEditso that we have a clear slate. - Look at process's memory consumption.
- Now repeat step #1 a second time.
- Now repeat step #2 a second time.
- Now look at memory consumption again. Is it twice the amount which was used when measured at step #3? Hopefully (but not guaranteed) it will not be twice the amount, because the memory allocated during step #4 will have a chance to re-use the memory allocated in step #1 which was freed in step #2?
- Press button to call
-
@JonB said in Qt's QTextEdit has big memory leak problem:
Look at process's memory consumption.
With a proper tool like e.g. valgrind or heaptrack, not with top nor Task Manager!
-
@JonB said in Qt's QTextEdit has big memory leak problem:
Look at process's memory consumption.
With a proper tool like e.g. valgrind or heaptrack, not with top nor Task Manager!
@Christian-Ehrlicher
Well, to be fair, yes and no. I am perfectly aware of the distinction. However, as was the case recently in another investigation of mine, what I was interested in was indeed the consumption of free memory from the OS rocketing in a Qt app. I precisely did want to know whattoporfreeor/proc/meminfowere showing, I had no interest in whatvalgrindmight or might not indicate. It does depend on what you are trying to investigate. -
@cyberpunker
Well, it makes sense to me that disabling the undo buffer should save a lot of memory in the case of what your code does. But you say not.You cannot assume that memory consumed by a C++/Qt program will be returned to the operating system on freeing variables. It would not be unexpected that this memory is returned to the pool of available memory to be reused by your program, but not deallocated from your program back to the OS. That's not how memory deallocation typically works.
What you should test is:
- Press button to call
setdata()once. - Press button to call
cleardata()once. Preferably have that actually delete and recreatetextEditso that we have a clear slate. - Look at process's memory consumption.
- Now repeat step #1 a second time.
- Now repeat step #2 a second time.
- Now look at memory consumption again. Is it twice the amount which was used when measured at step #3? Hopefully (but not guaranteed) it will not be twice the amount, because the memory allocated during step #4 will have a chance to re-use the memory allocated in step #1 which was freed in step #2?
I change the QTextEdit to QPlainTextEdit .
My test :
bootup : 56MB ( it is too big I think , just so little a demo )setdata : 279 MB
cleardata: 180MB ( does not release all )setdata : 279 MB
cleardata: 180MBsetdata : 279 MB
setdata : 459 MB
cleardata: 262MB ( does not release all )If it can release cleanly , I would appreciate it .
- Press button to call
-
@JonB said in Qt's QTextEdit has big memory leak problem:
Look at process's memory consumption.
With a proper tool like e.g. valgrind or heaptrack, not with top nor Task Manager!
I compile and run the Application.exe of Qt's example which is a simple text edit, repeat paste text into it , make the memory consumption roket up , then delete them all , the phenomenon recurrs.
-
I compile and run the Application.exe of Qt's example which is a simple text edit, repeat paste text into it , make the memory consumption roket up , then delete them all , the phenomenon recurrs.
@cyberpunker And how do you measure?
-
@cyberpunker And how do you measure?
Xfce's task manager
-
Xfce's task manager
quoting @Christian-Ehrlicher:
With a proper tool like e.g. valgrind or heaptrack, not with top nor Task Manager!
Regards
-
quoting @Christian-Ehrlicher:
With a proper tool like e.g. valgrind or heaptrack, not with top nor Task Manager!
Regards
any problem with xfce's task manager ?
I run valgrind in qtcreator, it can't endup ,so I give up.
-
any problem with xfce's task manager ?
I run valgrind in qtcreator, it can't endup ,so I give up.
@cyberpunker said in Qt's QTextEdit has big memory leak problem:
any problem with xfce's task manager ?
The OS does not display all freed memory instantly. Only if new memory requirements appear, the freed memory is taken into account.
So what you see in task manager is only updated if required.
-
I change the QTextEdit to QPlainTextEdit .
My test :
bootup : 56MB ( it is too big I think , just so little a demo )setdata : 279 MB
cleardata: 180MB ( does not release all )setdata : 279 MB
cleardata: 180MBsetdata : 279 MB
setdata : 459 MB
cleardata: 262MB ( does not release all )If it can release cleanly , I would appreciate it .
@cyberpunker said in Qt's QTextEdit has big memory leak problem:
setdata : 279 MB
cleardata: 180MB ( does not release all )
setdata : 279 MB
cleardata: 180MBThis part at least confirms my suggestion that your program will be able to re-use memory which gets freed, does it not?
-
Hi,
Since it's a log and you likely are going to scroll through it, you might want to consider using a QListView and have one row per line of your log.
-
Hi
When using TextEdit as log viewer , its often a good idea to
use
setUndoRedoEnabled(false);
so it doesn't keep a copy around to be able to undo text changes.Oh. sorry. already mentioned.