Seite 1 von 1

QGraphicsView, Speicherbedarf und was mach ich falsch ?

Verfasst: 5. Februar 2009 21:11
von quit
Hi Folks,

ich habe folgendes Problem, welches sich hoffentlich recht einfach an dem Qt-Beispiel examples\graphicsview\collidingmice nachvollziehen lässt.

modifiziert man da den Code aus der main.cpp, Zeile 67

Code: Alles auswählen

    for (int i = 0; i < MouseCount; ++i) {
        Mouse *mouse = new Mouse;
        mouse->setPos(::sin((i * 6.28) / MouseCount) * 200,
                      ::cos((i * 6.28) / MouseCount) * 200);
        scene.addItem( mouse );
    }
exemplarisch zu

Code: Alles auswählen

  for( int j = 0; j < 1000000; j++ ) {
    for (int i = 0; i < MouseCount; ++i) {
        Mouse *mouse = new Mouse;
        mouse->setPos(::sin((i * 6.28) / MouseCount) * 200,
                      ::cos((i * 6.28) / MouseCount) * 200);
        scene.addItem( mouse );
        scene.removeItem( mouse );
        delete mouse;
    }
    scene.clear();
  }
und fuehrt es aus, steigt der Speicherkonsum stetig. Wenn ich die Doku richtig lese, müssten sowohl scene.removeItem( mouse ) und delete mouse als auch scene.clear das Item mouse entfenren und restlos löschen. Es bleibt aber immer ein Rest nicht freigegebener Speicher. Mache ich irgendwas falsch, muss man noch an einer weiteren Stellen ansetzen?

Weder in der Forensuche noch sonstwo hab ich einen Lösungsansatz finden können, Debug-Versuche haben mich auch nicht wirklich weitergebracht.

Kompiliert wurde qt und das Beispiel mit vs2008 Prof, auf nem 32bit XP Prof.

EDIT: wahrscheinlich wäre noch hilfreich zu sagen, dass ich bis jetzt 4.4.0 und 4.4.3 getestet habe.

vielen Dank!

Gruss

Verfasst: 5. Februar 2009 22:30
von Christian81
Was soll der Code überhaupt bwirken? Warum immerzu ein neues Mouse-Objekt erzeugen??
Ich würde einen Memchecker benutzen - leider gibts unter Windows nichts freies. Unter Linux gibts ja valgrind...

Verfasst: 5. Februar 2009 22:35
von franzf
Liegt wohl daran, dass QGraphicsScene ein QObject ist, und da ist einiges komplizierter ;)
Da landet schon mal ein event (SIGNAL) auf dem Stack und es wird nicht bearbeitet, weil die EventLoop noch nicht läuft.
Du kannst den Speicherverbrauch konstant halten, in dem du in jedem der 1000000 Durchgänge nach dem scene.clear() ein QApplication::processEvents() einfügst.
Bei mir braucht das dann (laut top) nur 1.0 MB im RAM.

Also etwa so:

Code: Alles auswählen

Mouse *mouse;
    for( int j = 0; j < 1000000; j++ ) {
        qDebug() << j;
        for (int i = 0; i < MouseCount; ++i) {
            mouse = new Mouse;
            mouse->setPos(::sin((i * 6.28) / MouseCount) * 200,
                        ::cos((i * 6.28) / MouseCount) * 200);
                        scene.addItem( mouse );
                        scene.removeItem( mouse );
                        delete mouse;
                        mouse = 0;
        }
        scene.clear();
        QApplication::processEvents();
    }
Grüße
Franz

@Christian:
Ich glaub er hat gedacht ein MemLeak in Qt gefunden zu haben, aber ich glaub da muss man schon länger suchen ;)

Verfasst: 5. Februar 2009 22:35
von quit
Hi,

der Code ist an sich sinnlos, er soll nur das Problem reproduzierbar machen.

Verfasst: 5. Februar 2009 22:46
von quit
mmh, ok stimmt, das ist ein Ansatz. Das hab ich nicht bedacht, danke. Leider wird die Eventloop in dem Context, in dem auf das Speicherleck im zusammenhang mit den QGraphicsScenes usw, regelmässig abgearbeitet, was wohl heißt, dass ich in eine andere Richtung suchen muss...nochmal danke!


EDIT: Naja, ein Speicherleck in den Qt-Lib hab ich jetzt nicht als erstes vermutet :D , eher sowas wie ein Undo-Stack, oder irgendwelche anderen History-Funktionen.

Gruss

Verfasst: 5. Februar 2009 23:05
von franzf
Also, wenn du ewig in einer Schleife sitzt, läuft da auch kein event-processing. Das musst du dann auch manuell anschmeißen, auch wenn die eventloop läuft.