Kontinuierlich anwachsender Speicherbedarf

Alles rund um die Programmierung mit Qt
odt
Beiträge: 128
Registriert: 12. August 2010 11:49
Kontaktdaten:

Re: Kontinuierlich anwachsender Speicherbedarf

Beitrag von odt »

Hallo Markus
Die angesprochenen Bereiche sehe ich nicht gerade als "Basisfunktionalität". Hier würde wohl viel für Maschinencode, Shader resp. SQL sprechen.

Hallo Tillmann
Ich hatte früher mal einen ähnlichen Fall, wenn ich mich richtig erinnere, mit einer M$-Datenbank. Eine neuere Version des Datenbank-Treibers hatte das Problem gelöst.
Versuch den Leak mit einer anderen Datenbank zu reproduzieren.
Viele Grüsse
Reto
ODT Informatik GmbH, Reto Tschofenig
harry_m
Beiträge: 74
Registriert: 26. April 2010 23:16

Re: Kontinuierlich anwachsender Speicherbedarf

Beitrag von harry_m »

Markus hat geschrieben: Und was würde man für diese "Basisfunktionalität" einsetzen?
Ach, wenn ich die Ausführungen vom RBaum genauer durchlese, dürfte es sehr wohl möglich sein, Qt für alles einzusetzen.

Denn wenn man den durch "Parent" funktionierende Mechanismus für den ungebührlichen Speicherverbrauch verantwortlich sein sollte, dann müsste man für die Dinger, die er als "gefährlich" beschreibt, diesen Mechanismus eben NICHT benutzen. Nicht jede Klasse muss zwangsläufig von QObject abgeleitet werden. Im "sensiblen" Bereich wird es wohl möglich sein, eigene Klassen zu schreiben: und dabei vom Destructor Gebrauch machen.

Abgesehen davon bin ich mir nicht sicher, ob diese Schlussfolgerungen ohne Weiteres auf alle Klassen übertragbar sind. Letzten Endes funktionieren die Symbian- und MeeGo-Geräte auf sehr "schmalen" Hardware doch ganz ordentlich. Und die Klassen wie z.B. "QTcpSocket", "QTcpServer" oder "QNetworkSession" sind bestimmt so programmiert, dass sie die Ressourcen dieser kleinen Gerätschaften nicht über Gebühr belasten. (Das sind übrigens auch Klassen, die nach meinem Verständnis nicht ohne weiteres in die Aussage "Qt ist nur ein GUI Framework" richtig passen wollen. Qt entstand sehr wohl aus GUI-Framework. Aber die Tatsache, dass man damit inzwischen das ganze KOffice programmiert hat, dürfte ein sanfter Hinweis darauf gedeutet werden, dass im Laufe der Zeit noch einiges dazu gekommen ist. Ich sage nur "Krita": mit GUI-lastigem Framework alleine ließe es sich nicht umsetzen).

@RBaum: besten Dank für den Beitrag. Hat mir sehr gut gefallen und war sehr hilfreich, weil einige Sachen bestätigte, die ich mir selbst zusammengereimt habe, aber doch nicht sicher wusste. Es gibt in der "QtWelt" leider viele Sachen, die irgendwie selbstverständlich sind, aber selten (oder gar nicht) erwähnt werden. Das macht es für den Einsteiger teilweise sehr schwierig. Ein Bekannter meinte mal, dass Qt zwar sehr schön sei, aber doch "wenig intuitiv". Im gewissen Maße muss ich ihm leider Recht geben. Es gibt viele Sachen, auf die man ohne einen expliziten Hinweis einfach nicht kommt.

Prima. Derartige Beiträge habe ich hier schon länger vermisst.
Zwei Tragödien gibt es im Leben: die eine - nicht zu bekommen, was das Herz wünscht, und die andere: es doch zu bekommen. (Oscar Wilde)
RHBaum
Beiträge: 1436
Registriert: 17. Juni 2005 09:58

Re: Kontinuierlich anwachsender Speicherbedarf

Beitrag von RHBaum »

Und was würde man für diese "Basisfunktionalität" einsetzen?
In meinen Faellen kommts dann auf die Libs an, die ich so brauche, die bestimmen meinen "Style" dann.
Oft wirds C++ generisch, also mit Tamplates und sonst "Normales" C++.
Wenns geht verwend ich auch die STL/Boost
Selten überschreib ich den Standard-STL-Allokator.
In wenigen Fallen wird es dann "C Style" im C++ gewand
Ist es möglich, dass der ODBC-Treiber für dieses Anwachsen des Speichers verantwortlich ist.
Lange her da hab ich mal was mit Oracle und ODBC und dann OCI gemacht. Aber generell .... Datenbank "treiber " optimieren, sprich cachen, auch gern.
Kommt auf die SQL Statements an die du abschickst, und was für cursor (clientseitig, serverseitig) du verwendest. Da kommt meist ordentlich was zusammen.
Und meist sind die Teile so programmiert, das sie speicher den sie mal haben nicht ohne grund wieder hergeben . Das kann viel ausmachen ...

Wenn es dich wirklich intressiert, fuer windows gibts auch libs, die sich ins Speichermanagment einklinken und die Allokationen loggen und statistiken erstellen.
Manchmal tuts ein Profiler auch scho ...
Zumindest bekommst da die Info, welches modul (die exe oder die dll's) in deinem Prozess welchen speicher sich holen. Normal siehst das ohne hilfsmittel nicht.
Wir haben Intels Vtune hier im einsatz z.b.
Aber einfach ist das nicht, das einarbeiten ist .... lohnt also wirklich nur wenn sich deine Lebensqualitaet dadurch erheblich verbessern wuerd :-)
Und die Klassen wie z.B. "QTcpSocket", "QTcpServer" oder "QNetworkSession" sind bestimmt so programmiert, dass sie die Ressourcen dieser kleinen Gerätschaften nicht über Gebühr belasten.
Naja, mit anderen Libs / nativer Programmierung kann man da scho ordentlich was rausholen ^^
Aber macht dann auch wesentlich mehr arbeit. Meist sind die Apps auch ned so gross, also da werden mal 1-2 Objekte der Art angelegt, da iss der Overhaed dann den Aufwand nicht wert, darueber nachzudenken.

Ich sag immer ("und dafuer werd ich oft gescholten") "Qt + c++" ist wie Java programmieren.
Man gibt die Kontrolle ueber seine Ressourcen ab, und erspart sich dadurch Arbeit und einige Dinge, über die sich man Gedanken machen muesste.
Auf der anderen Seite, wennn man sich in einem "Programm" nie Gedanken ueber Ressourcen macht, warum programmiert man dann in C++ ???
Zumindest die Frage muss man sich gefallen lassen, natuerlich gibts auch dann gute Gründe für Qt :

C++ programmierer sollten damit auch zurande kommen, auch wenn vieles ungewohnt ist, trotz der gleichen Sprache ...
Es ist fuer viele Plattformen verfügbar ...

Aber die "Königsdisziplin" sind immer noch grosse modulare Projekte, wo man durch die Modularisurung für jeden Teilaspekt die richtigen Libs und Technicken auswaehlen kann, und die zu nem grossen und ganzen verbinden.
Ohne dabei die Sprache zu wechseln ...mit mehreren "Sprachen" gehts natuerlich auch, aber wer mal mit Swig oder JNI oder Python auf C Ebene rumgemacht hat, weiss es zu schätzen das man zwischen GUI und Business-Logik auf C++ ebene Bleiben kann, das ist purer Luxus dagegen :-)

Ciao ...
Zuletzt geändert von RHBaum am 28. November 2012 12:34, insgesamt 1-mal geändert.
odt
Beiträge: 128
Registriert: 12. August 2010 11:49
Kontaktdaten:

Re: Kontinuierlich anwachsender Speicherbedarf

Beitrag von odt »

ODBC-Treiber für dieses Anwachsen des Speichers verantwortlich ist.
vielleicht hilft es auch, die Db-Verbindung ab und zu zu closen.
"Qt + c++" ist wie Java programmieren
kann ich nur bestätigen, ausser das es mehr Spass macht und mehr Funktionalität bietet. Nur der Bereich Web (serverseitig) fehlt. Dafür habe ich noch keinen schönen Weg gefunden.
die zu nem grossen und ganzen verbinden
ist manchmal eine Herausforderung. Wer schon mal eine mit MinGW kompilierte Library mit einer nur in MSC Vorliegenden (wie OCI) kombinieren wollte.. Oder wenn noch Cross-Plattform dazu kommt, etwa LevelDB auf Meego...
ODT Informatik GmbH, Reto Tschofenig
RHBaum
Beiträge: 1436
Registriert: 17. Juni 2005 09:58

Re: Kontinuierlich anwachsender Speicherbedarf

Beitrag von RHBaum »

ist manchmal eine Herausforderung. Wer schon mal eine mit MinGW kompilierte Library mit einer nur in MSC Vorliegenden (wie OCI) kombinieren wollte..
Auch c++ hat da seine Grenzen :-)
Wenn man Binärkompatiblitaet braucht, ist c++ halt nen Problem.
Zum glueck koennen auch C++ compiler reine C schnittstellen erzeugen und bedienen :-)

Aber grad in Sachen Schnittstellen ist Qt auch eher nen Problemfall ....
Qt klassen in Moduluebergreifenden Schnittstellen sind eh aua -> bedingen selbe QT version und einige Compilerflags/QT einstellungen dürfen ned angeruehrt werden (oder muessen einheitlich sein)
Verwenden von Qt klassen in Modulen, die keine QT abhaengigen Schnittstellen haben -> kann problem werden weil QT die Minor Versionen nicht im Dateinamen hat und die Minorversionen teilweisse nicht binaerkompatibel sind.
Ein gegen qt 4.4.3 gelinktes Modul laeuft z.b. hier nicht mit ner 4.8.2 QtCored4.dll
Das gegen die 4.8.2 gelinkte modul laeuft natuerlich nicht mit einer 4.4.x QtCored4.dll
Ein Teufelskreiss ^^ Besonders Lustig wenn der "erzeuger" des Moduls ein externer Zulieferer ist, und recht unkooperativ in Sachen Änderungen / Weiterentwicklung ist ....

in Linux hat man die .so versionierung (version im Dateinamen), womit man das Problem umgehen kann, warum in windows nicht die minor version im Dateinamen.

Ciao ...
Markus
Beiträge: 105
Registriert: 31. Januar 2005 16:21

Re: Kontinuierlich anwachsender Speicherbedarf

Beitrag von Markus »

Tilman Räger hat geschrieben:[...] Ist es möglich, dass der ODBC-Treiber für dieses Anwachsen des Speichers verantwortlich ist. [...]
Welche ODBC-Datenbanken sind es? Wird auf eine Access-DB, MS-SQLServer oder Excel zugegriffen? Weil ich arbeite viel mit MySQL und Oracle (OCI) und habe dieses Verhalten noch nicht festgestellt.
Tilman Räger
Beiträge: 189
Registriert: 6. Juni 2007 15:23
Wohnort: Göttingen

Re: Kontinuierlich anwachsender Speicherbedarf

Beitrag von Tilman Räger »

Hallo,
Markus hat geschrieben:
Welche ODBC-Datenbanken sind es? Wird auf eine Access-DB, MS-SQLServer oder Excel zugegriffen? Weil ich arbeite viel mit MySQL und Oracle (OCI) und habe dieses Verhalten noch nicht festgestellt.

Ich selber habe das Verhalten (mit MySQL via ODBC noch nicht so eindeutig feststellen können, was der Kunde beim Testen verwendet, weiss ich nicht. Geplant ist, möglichst viele Datenbanken anbinden zu können - das Programm soll quasie eine standardisierte Schnittstelle zwischen verschiedenen Datenbanken und Steuerurngsrechnern bilden. Dabei wird dann auch die Datenbank ziemlich strapaziert (z.B. kontinuierlich alle sec in die Datenbank geschrieben und das über Stunden!
Ich werde jetzt auf jedenfall erst einmal versuchen, die Datenbank-Verbindung öfters mal zurückzusetzten (vielleicht am Anfang nach jedem Zugriff, wenn das etwas bringt, die Intervalle vielleicht wieder etwas vergrössern.

Gruss
Tilman (Räger)
odt
Beiträge: 128
Registriert: 12. August 2010 11:49
Kontaktdaten:

Re: Kontinuierlich anwachsender Speicherbedarf

Beitrag von odt »

Regel Nr 1: Reproduzieren! Versuch den Fehler zu reproduzieren, die Umgebung des Kunden möglichst nah nachzubauen. Sonst wirst Du eher im Dunkeln stochern.
ODT Informatik GmbH, Reto Tschofenig
Markus
Beiträge: 105
Registriert: 31. Januar 2005 16:21

Re: Kontinuierlich anwachsender Speicherbedarf

Beitrag von Markus »

Tilman Räger hat geschrieben: [...] Ich selber habe das Verhalten (mit MySQL via ODBC noch nicht so eindeutig feststellen können, was der Kunde beim Testen verwendet, weiss ich nicht. [...]
Hallo!

Wie odt schon sagte, würde ich meine Testumgebung sehr ähnlich wie das Kundensystem aufbauen, um den Fehler zu reproduzieren. Und wenn es möglich ist, würde ich den MySQL-Treiber für Qt kompilieren und in einer definierten Testphase beim Kunden verwenden. Besser ein stabiles System und in der Konfigurierbarkeit zu Beginn eingeschränkt sein als die jetzigen Probleme. Weil z.Z. weiss ich nicht, warum ein Kunde öfters mal das DBMS wechseln sollte oder ich habe keine Idee, was Dein Programm macht. :wink:

Viele Grüße,
Markus
Tilman Räger
Beiträge: 189
Registriert: 6. Juni 2007 15:23
Wohnort: Göttingen

Re: Kontinuierlich anwachsender Speicherbedarf

Beitrag von Tilman Räger »

Hallo,
nach einiger Zeit noch einmal das selbe Thema. Ich habe hier eine Anwendung (erstellt von meinem Kunden :-) - die lediglich eine ODBC-Datenbank aufmacht, 100000 Datensätze in diese hineinschreibt und die Datenbank wieder schließt. Lässt man die Datenbank die ganze Zeit offen, bleibt der Speicherverbrauch konstant, schließt man die Datenbank nach jeder Transaktion und macht das QSqlQuery-Objekt platt, so steigt der Speicherbedarf langsam aber kontinuierlich. Es macht dabei keinen (großen) Unterschied ob man die Query vor dem delete noch mit QSqlQuery::clear() oder QSqlQuery::finish() aufräumt oder nicht.
Dieses Anwachsen des Speichers erfolgt nur unter Windows mit ODBC-Treiber. MySQL-Treiber (direkt) habe ich unter Windows bisher nicht testen können, da sich der Treiber bei mir nicht erstellen lässt (s. anderer Thread)

Vielleicht hat ja jemand noch einen Tip für mich - ggf. auch nach Blick auf die unten angehängten Quellen.

Gruß
Tilman (Räger)
Dateianhänge
Insert.zip
(3.4 KiB) 265-mal heruntergeladen
odt
Beiträge: 128
Registriert: 12. August 2010 11:49
Kontaktdaten:

Re: Kontinuierlich anwachsender Speicherbedarf

Beitrag von odt »

Hallo Tillmann

Auf die Schnelle ist mir kein gravierender Fehler im insertThread::run() ins Auge gestossen. Konntest Du das Problem inzwischen mit dem MySQL-Treiber kontrollieren?

Viele Grüsse
Reto
ODT Informatik GmbH, Reto Tschofenig
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Re: Kontinuierlich anwachsender Speicherbedarf

Beitrag von franzf »

MMn. ist problematisch, dass es EIN thread-Objekt gibt, der Benutzer aber beliebig die Checkbox an/ausmachen kann und den "start"-button clicken. insertThread::holdConnection ist nicht durch nen Mutex geschützt, dadurch kann es passieren, dass es mitten in der Loop vom User getoggled wird und dann plötzlich QSqlQuery-Objekte verloren gehen.
Im übrigen hat "ein query Objekt mit vielen queries verwenden" nichts mit "Verbindung halten" zu tun.
Außerdem ist das verschicken von 100000 queries extrem aufwändig. Warum packst du denn nicht einfach ALLE 100000 Werte in einen einzigen query?
Und es gibt QString::number(), also kein Grund hier über stringstream + c_str() zu gehen.
Tilman Räger
Beiträge: 189
Registriert: 6. Juni 2007 15:23
Wohnort: Göttingen

Re: Kontinuierlich anwachsender Speicherbedarf

Beitrag von Tilman Räger »

Hallo,
hat ein wenig gedauert, bis ich die Antwort gelesen hatte - aber einige Kommentare hierzu:

Zum einen, der Autor dieses Progrämmchens entwickelt normalerweise nicht in C++ - daher seien diverse Unsauberheiten verziehen (u.a. der Versuch, im DB-Thread eine Messagebox aufzuziehen. Also bitte alle punkte die die Sicherheit und Funktionlität des Programms angehen, einfach mal ignorieren :-)
Das das verschicken von 100000 Queries aufwändiger ist, als mal eine mit 100000 Werten (was, denke ihc, auch nicht ganz trivial wäre, alleine den SQL-Request zu bauen) ist auch klar.

Aber: Gerade darum geht es, das die Methode, die mit der Option 'HoldConnection' verwendet wird
also DB erzeugen, öffnen, x Queries ausführen dann schließen den Speicherbedarf stabil lässt, wohingegen es bei der Variante jedesmal die DB zu öffnen und wieder zu schließen, zu einem kontinuierlich anwachsenden Speicherbedarf kommt. Dieser ist allerdings nicht so groß, das man es mit deutlich weniger Cyclen eindeutig sehen würde, sondern geht dann ein wenig im Rauschen unter.

Leider konnte ich das ganze noch nicht mit direktem Zugriff auf MySQL nachvollziehen - nachdem ich mir MySQL neu installiert und den MySQL-Treiber übersetzt bekommen habe, läuft auf diesem Rechner überhaupt kein Datenbankzugriff mehr :-(
Vermutlich muss ich über die Feiertage erst einmal alle Qt- und MySQL-Versionen deinstallieren und das ganze neu aufsetzten. :-(

Tilman
Antworten