Memory leak or misunderstanding with QList<QObject*> as model
Page |
1 |
Hi there,
I have the following code:
- void QmlApplicationViewer::updateModel()
- {
- for(size_t i = 0; i < 100; ++i)
- QDeclarativeContext* pContext = rootContext();
- {
- pEntry->deleteLater();
- }
- }
This code is fired up every second by the timer and constantly leaking. I don’t understand why it is leaking at all. Am I missed something or I found a bug?
Additional info:
QML file:
- import QtQuick 1.0
- Rectangle {
- width: 360
- height: 360
- Column {
- Repeater{
- model: Model
- delegate: Text{
- text: model.modelData.name;
- }
- }
- }
- }
UserData:
- {
- Q_OBJECT
- QString m_strName;
- public:
- m_strName(strName)
- {
- }
- return m_strName;
- }
- {
- m_strName = strName;
- }
- signals:
- };
QmlApplicationViewer – is the class generated by the QtCreator.
full project: http://www.sendspace.com/file/z37b0d
17 replies
It does not. QList just destroys itself it doesn’t free memory allocated for QObject*Memory is freed by extracting model from the QML
You are trying to extract model which has been destroyed already. Try to debug and see how many times your for loop runs.. it must be zero if I am not wrong..
You are passing a value here as Model. But Model will be destroyed after you come out of your function. So basically you are trying to use something that has been destroyed already.
When you create your “Model”, it have CppOwnership by default. But when you set it to QML property, it will transfer the ownership to javascript if your “Model” have no parent. And the “Model” will be collected by javescript’s garbage collection and destroy when ref is 0. Also, create it from heap is the right way.
Is your for foreach loop running correct number of times..
I didn’t check the all 100 times but it executes many times I don’t have any suspicions about it.
And why do you do deleteLater rather delete pEntry??
Because those model element could be still in use in the QML itself and the app will crash with just a delete statement.
I’m pretty sure that the leak is not in the UserData* pointers but in the QtDeclarative itself but maybe I’m using it wrong?
When you create your “Model”, it have CppOwnership by default. But when you set it to QML property, it will transfer the ownership to javascript if your “Model” have no parent. And the “Model” will be collected by javescript’s garbage collection and destroy when ref is 0. Also, create it from heap is the right way.
So, I should not have the leaks in such a case, right? GC should delete it. But I have leaks. moreover when I extract the Model property I guarantee that the items will be deleted.
Why do you re-create your model every second at all? They are not meant to be used that way. Models are created once and then have their data updated and changed.
You are doing hundreds of memory allocations and deallocations every second. This is generally not a good idea – having a working garbage collection or not. If I remember correctly setting context properties requires the declarative engine to re-evaluate all bindings – which is again another expensive operation every second.
Rethinking your application design might be the most successful solution for your problem.
So, I should not have the leaks in such a case, right? GC should delete it. But I have leaks. moreover when I extract the Model property I guarantee that the items will be deleted.
GC might delete your object, but does not have to. deleteLater() possibly won’t delete your object if the script engine still references it.
Lukas Geyer, I’d like to do it another way but qt docs states unambiguously:
Note: There is no way for the view to know that the contents of a QList have changed. If the QList changes, it will be necessary to reset the model by calling QDeclarativeContext::setContextProperty() again.
It is from here [doc.qt.nokia.com]
GC might delete your object, but does not have to. deleteLater() possibly won’t delete your object if the script engine still references it.
I checked destructor and it is executed. I didn’t check it for all the object, though. Maybe the answer is here. So JavaScript owns each object in model? So it increments ref count? I have an app which has the similar(actually the project in this thread is just an excerpt from the actual app) code and it grows from ~30 Mb to ~300 Mb in few days. So if the GC works right then there should not be any problems because I delete objects with deleteLater() and GC works…
You must log in to post a reply. Not a member yet? Register here!



