Debugging small memory / cpu leaks
-
Hi
I've left my application running during the night wondering if it will be stable till morning. It was.
But i noticed an enormous memory consumption this morning. And also the application uses more and more cpu the longer it runs.How can i debug this? Its only a small amount.
CPU consumption goes from 10% -> 20%
RAM consumption goes from 2% -> 6%The software has to be stable for at least 2 days eventually. So my question is: How do i debug this?
I've tried Valgrind but i don't understand it yet.
Thanks.
-
Which version of QtQuick are you using? With Qt4.x/QtQuick1 there is a known leak in component creation (the engine is the parent of dynamically constructed components, so those components will not be destroyed until the engine is destroyed - which is generally on application shutdown). I forget the bug number which tracks this task, but it probably won't be addressed as QtQuick1 is basically in maintenance mode now, with most (if not all) effort being redirected toward QtQuick2.
In QtQuick2 this particular bug has already been resolved. Others may exist. In particular, it is worth noting that our integration with the V8 garbage collector isn't too great (more technically: I don't think we tell the V8 engine how big the "external resource" objects we allocate are - so V8 believes that all of the objects we allocate are simple <= 16 byte objects, which leads to fewer but hideously more expensive GC cycles). I'd be interested in knowing why the CPU consumption increases - as that suggests to me that "more work" is actively being done by your application (which suggests that objects are being kept alive, which have active bindings or animations; OR that your running into V8 GC or V8 profiling thread issues).
Without more information I can't really give a better answer, unfortunately. I'd suggest using the QML Analyzer / Profiler tool from QtCreator to get some traces of what your application is doing.
Cheers,
Chris. -
I'm using Qt5 with Qml2 on Archlinux. My solution to this problem is for now to simply outsource the whole multimedia stuff into dedicated processes.
So the Integration is not that great for now. Maybe i will use QWidgets for starters then and switch back when the application is more mature. The View logic is not the biggest deal anyway.As for the analyzing tools. Since the application runs in a endless loop, they wont hit an end. If i abort, i get some data but i couldn't locate any specific area.
For my application:
It is a QQuick.Window (qml tag) which houses a Image area which displays the property "source". From cpp i simply set this property with setProperty("source", value). I do this endlessly every 2 seconds.So i will get back to this as soon as it shows necessary to support some transitions and stuff.
[code]import QtQuick 2.0
import QtQuick.Window 2.0Window {
width: 360
height: 360
property string src
Image {
id: img
source: src
anchors.fill: parent
}
}
[/code][code]engine.addImageProvider(QString("imageProvider"), new Image_Provider);[/code]
[code]class Image_Provider : public QQuickImageProvider
{
public:
Image_Provider() : QQuickImageProvider(QQuickImageProvider::Image){}QImage requestImage(const QString &id, QSize *size, const QSize &requestedSize){ QImage img ("/home/sfuser/projects/qt_prototyping/media/images/"+id); (void)(size); (void)(requestedSize); return img; }
};[/code]
[code]comp = new QQmlComponent(e, QUrl("qml/MultiRegionTypePlayer/main.qml"));
p = qobject_cast<QQuickWindow*>(comp->create());[/code][code]void ImagePlayer::update(){
if (++i >= 4) i = 0;
p->setProperty("src",u[i]);
p->setVisible(i%2==0);
}[/code] -
You're certain that you're only creating one single "comp" and "p" instance? So you're saying that what "runs endlessly" is basically the update() function of the ImagePlayer, which you trigger manually in a loop of some kind from cpp?
Do you clear the image cache occasionally, to ensure that the engine isn't just caching images forever? What is "u" in the update() scope? Do the paths / uris in u change over time? If not, you shouldn't see cache proliferation but if they do, it definitely might be something to follow up.
The fact that all of this code is in C++ suggests that it isn't a V8 issue, so I doubt the GC behaviour is involved - although I might be wrong.
Does p->setProperty("src", u[i]) actually work as you expect (I mean, do the appropriate change signals get emitted for the Q_PROPERTY of the Window element, and retrigger the binding evaluation)? I assume it does, but just wondering, as my memory of that code is hazy. The "src" property is a "dynamic QML metaobject property" which have slightly different semantics to normal QObject properties.
Other than that I can't really offer any suggestions - valgrind really is the only other thing I'd suggest.
Cheers,
Chris. -
Thans for your answer.
So yea, "comp" and "p" are created in the constructor and therefore only once. "u" is an array with 4 pictures in it from which i randomly choose.
"update" is called from a timer and yes setProperty "src" does work as expected.Valgrind could not point my near any hint since i already know which class is leaking. Disabling that class stops the leaking which makes it pretty obvious. Maybe the *size and &requestedSize properties of the image provider have something to do with this?