Kontinuierlich anwachsender Speicherbedarf

Alles rund um die Programmierung mit Qt
Tilman Räger
Beiträge: 189
Registriert: 6. Juni 2007 15:23
Wohnort: Göttingen

Kontinuierlich anwachsender Speicherbedarf

Beitrag von Tilman Räger » 25. Oktober 2012 23:20

Hallo,

Nachdem die Antworten auf meine Fragen bzgl. Threads sowie Memory-Leaks mich ein ganz schönes Stück weitergebracht haben (Danke übrigens noch mal :-)
habe ich nun noch ein weiteres Problem.

Meine Anwendung wächst im Laufe der Zeit kontinuierlich (nach 2 h ca. 8 - 10 MB grösser als zu Beginn) enthält aber nach VLD keine MemoryLeaks. Ich habe mir nun eine Beispielanwendung gebaut (folgt morgen, da noch nicht ganz fertig), die nichts weiter macht, als zwischen 2 Anwendungen ein Socket zu öffnen, ein- oder mehrmals ein paar Byte (Fixtext) hin- und wieder zurückzusenden sowie das Socket dann wieder zu schliessen. Interessant ist hierbei für mich die Server-Seite (d.h. die Anwendung, die einen QTcpServer laufen hat, der auf einem Port lauscht und wartet, das die andere Anwendung kontakt aufnimmt).
Diese Anwendung wächst nahezu kontinuierlich an (Abnahme des Speicherbedarfs durch Löschen der Sockets (mittels pSocket->deleteLater()) ist praktisch nicht zu beobachten. Auch ist die Zunahme nicht regelmässig (also z.b. in jedem Cyclus 1 kB) sondern relativ unregelmässig. Selbst im Idle Zustand, wenn also der TcpServer lediglich auf neue Verbindungen wartet, konnte ich eine Zunahme beobachten.

Das ganze ist relativ kritisch, da die Anwendung als Dienst laufen soll, der Automatisierungsrechner mit Datenbanken zusammenbringt. Da ist ein kontinuierlich mehr Speicher benötigendes Programm natürlich nicht wirklich günstig, vor allem, wenn es u.U. Tage ohne Betreuung laufen soll.

vom Prinzipiellen Ablauf her läuft das ganze in etwa so :

Code: Alles auswählen

- QTcpServer instanz wird mit listen() aktiv geschaltet
- bei Signal 'newConnection' wird der Socket übernommen, überprüft, ob schon eine Verbindung besteht (falls ja wird der Socket mittels disconnectFromHost() geschlossen)
- bei Signal 'readyRead' werden die anstehenden Bytes vom Socket gelesen, solange welche verfügbar sind. 
- Im Anschluss werden diese Daten einfach wieder zurückgeschickt. 
- nach 10 sec. ohne Datenempfang wird der Socket mittels disconnectFromHost() geschlossen. 
- bei Signal 'QTcpSocket::disconnected() wird der Socket mittels deleteLater() zur Vernichtung freigegeben
Im Prinzip also eine ziemlich einfache Sache. Meine Fragen hierzu:

- Gibt es bei der Skizzierten Vorgehensweise irgendwelche bekannten Fallstricke die ein solches Verhalten erklären würden?
- muss ich u.U. bei einer Qt-Applikation generell mit einem solchen Verhalten rechnen (ich denke mal eher nein)
. Sind vielleicht schon aus meiner Skizze Denkfehler oder fehlerhafte Ansätze zu erkennen?

Ein Problem hatte ich übrigens bei der Sendenden Anwendung - wenn ich in der Empfangenden vor dem Antworten nicht alle zur Verfügung stehenden Bytes (while (pSocket->bytesAvailable()) ) gelesen hatte, stürzte mir die andere Anwendung ab. Irgendwie wurde anscheinend innerhalb der Ausführung des sendens schon ein readyRead-Signal ausgelöst und der Slot direkt angesprungen. Dies wurde besser, nachdem ich die connection zw. readyRead und dem zugehörigen Slot auf QueuedConnection umgestellt, und endgültig beseitigt nach der genannten Änderung in der Gegenstelle. Hat hier jemand solche Effekte schon mal beobachtet und kann sie zuordnen?

Danke

Tilman (Räger)

odt
Beiträge: 128
Registriert: 12. August 2010 11:49
Kontaktdaten:

Re: Kontinuierlich anwachsender Speicherbedarf

Beitrag von odt » 26. Oktober 2012 10:38

Hallo Tillman

Grundsätzlich scheint Deine Vorgehensweise io zu sein.

Qt behauptet von sich, dass es keinen Speicher verliert. Aufgrund einiger Tricks (Lazy-Init, Caching) kann es aber sprunghafte Memory-Allozierungen geben. Quasi so was wie
UsedMemory: 20
irgendeineQfunc();
UsedMemory: 40
Aber ein erneuter Aufruf macht's nicht schlimmer
irgendeineQfunc();
UsedMemory: 40
Du scheinst jedoch ein kontinuierlicher Verlust zu haben. Dies deutet eher auf ein QObject, dass zwar einen Parent hat, aber nicht direkt gelöscht wird. PS: DeleteLater löscht erst im Event-Loop. Da Du aber mit Signal/Slots arbeitest, ist es vermutlich nicht die Ursache.

Dein zweites Problem liegt an der Netzwerk-Architektur. Grundsätzlich ist es nicht vorhersagbar, wie die Netzwerkdaten paketiert werden. Im readyRead kann es sein, dass ein Datenpaket nicht vollständig im Buffer liegt. Abstürzen sollte Dein Programm hier nie! Sonst hat der Hacker ein schweres Spiel (phu, eine erste Telnet-Verbindung und schon stürzt es ab, wie soll ich da reinkommen?) Dass Du hier mit den Signal-Slot-"Typen" rumspielst, wird eher die Symptome verschleiern.

Viele Grüsse
Reto
ODT Informatik GmbH, Reto Tschofenig

Tilman Räger
Beiträge: 189
Registriert: 6. Juni 2007 15:23
Wohnort: Göttingen

Re: Kontinuierlich anwachsender Speicherbedarf

Beitrag von Tilman Räger » 26. Oktober 2012 11:00

odt hat geschrieben:
Qt behauptet von sich, dass es keinen Speicher verliert. Aufgrund einiger Tricks (Lazy-Init, Caching) kann es aber sprunghafte Memory-Allozierungen geben. Quasi so was wie
UsedMemory: 20
irgendeineQfunc();
UsedMemory: 40
Aber ein erneuter Aufruf macht's nicht schlimmer
irgendeineQfunc();
UsedMemory: 40

Du scheinst jedoch ein kontinuierlicher Verlust zu haben. Dies deutet eher auf ein QObject, dass zwar einen Parent hat, aber nicht direkt gelöscht wird. PS: DeleteLater löscht erst im Event-Loop. Da Du aber mit Signal/Slots arbeitest, ist es vermutlich nicht die Ursache.
Eben eine solche sprunghafte Memory-Allozierung habe ich möglicherweise vorliegen (lange Zeit kein Zuwachs, dann plötzlich 1, 2 MB mehr, dann wieder nichts, dann wieder etc. Diesen Verdacht hatte ich auch schon, das irgendwelche Qt-Objekte (QList, o.ä.) Platz allozieren, nach einiger Zeit bemerken, es reicht nicht und noch einen Schluck aus der Pulle nehmen - aber nie etwas davon freigeben, bevor sie nicht weggeräumt werden. Das sollte eigentlich dazu führen, das das Programm - solange diese Bereiche nicht irgendwo tot im Speicher liegen, sondern dynamisch wiederverwendet werden - bis zu einem gewissen Grenzwert wächst und dann nicht weiter. Damit könnte ich leben!

Zu der Sache mit deleteLater: Ich habe zu anfang versucht, die Objekte (speziell QTcpSocket-Objekte) direkt zu löschen. Aber selbst die Variante

Code: Alles auswählen

QTcpSocket* pSocket;
...
pSocket->disconnectFromHost();
pSocket->close();
delete pSocket;

führte unweigerlich zum Abschmieren des Programms. Qt empfiehlt deleteLater :-)
odt hat geschrieben:
Dein zweites Problem liegt an der Netzwerk-Architektur. Grundsätzlich ist es nicht vorhersagbar, wie die Netzwerkdaten paketiert werden. Im readyRead kann es sein, dass ein Datenpaket nicht vollständig im Buffer liegt. Abstürzen sollte Dein Programm hier nie! Sonst hat der Hacker ein schweres Spiel (phu, eine erste Telnet-Verbindung und schon stürzt es ab, wie soll ich da reinkommen?) Dass Du hier mit den Signal-Slot-"Typen" rumspielst, wird eher die Symptome verschleiern.
abgesehen davon, das die Anfragen in der Regel recht klein sind, kann ich das inzwischen verkraften. Das Programm (die real-Version :-) ) liest solange bis es einen abgeschlossenen Request findet, gibt diesen dann an die Verarbeitung weiter und liest weiter, solange Bytes da sind. Bleibt ein unvollständiger Request liegen, wird halt im nächsten 'ReadyRead' weitergelesen. Diese kleckerles-weise lesung hat schon funktioniert, da ich am Anfang aufgrund eines Fehlers quasi nach jeder Zeile abgesetzt habe. Allerdings habe ich bisher noch nie Anfragen bekommen, die segmentiert waren.

Wie ist es eigentlich genau: wenn ich über den QTcpServer eine Verbindungsanfrage hereinbekomme, und stelle beim erhaltenen Socket (nextPendingConnection()) fest, das der nicht für mich geeignet ist.
- a) wenn ich diesen schliesse (mittels close(), bzw. disconnectFromHost()) - bin ich für das Wegräumen verantwortlich oder ist das Sache von Qt?
- b) ist es möglich, einen solchen Socket quasi offen zu lassen und in der Queue zu belassen, für den Fall, eine andere Anwendung interessiert sich dafür?

Gruss
Tilman (Räger)

odt
Beiträge: 128
Registriert: 12. August 2010 11:49
Kontaktdaten:

Re: Kontinuierlich anwachsender Speicherbedarf

Beitrag von odt » 26. Oktober 2012 11:07

Sprunghaft ja, aber nur EINMAL.

a) Du bist für die Sockets zuständig, d.h. deleteLater aufrufen.

Eine andere Anwendung kann nicht auf auf dem gleichen Port "hören". Daher ist b) unlogisch.

Viele Grüsse
Reto
ODT Informatik GmbH, Reto Tschofenig

Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Re: Kontinuierlich anwachsender Speicherbedarf

Beitrag von Christian81 » 26. Oktober 2012 11:27

Und wie ich schon im anderen Thread gesagt habe: Für soetwas gibt es unter Linux 'valgrind' und unter Windows komerzielle Tools. Also warum machst Du noch einmal einen Thread auf?
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung

Tilman Räger
Beiträge: 189
Registriert: 6. Juni 2007 15:23
Wohnort: Göttingen

Re: Kontinuierlich anwachsender Speicherbedarf

Beitrag von Tilman Räger » 26. Oktober 2012 11:57

Hallo,
Christian81 hat geschrieben: Und wie ich schon im anderen Thread gesagt habe: Für soetwas gibt es unter Linux 'valgrind' und unter Windows komerzielle Tools. Also warum machst Du noch einmal einen Thread auf?
Ich habe es mir lange überlegt, ob oder ob nicht - bin aber zum Schluss gekommen, das es zwar der selbe Dunstkreis, aber vielleicht doch soweit unabhängig davon ist, das es einen neuen Thread rechtfertigt.
Der erste Thread bezog sich auf die Tools - dieser speziell auf das Verhalten, ob da vielleicht etwas Qt-Spezifisches dabei ist, bzw. wo mein Fehler liegen könnte. Nach den Tools - Visual Lead Detector, valgrind habe ich bisher noch nicht bemüht, lint hat bei mir momentan ein Problem (die mir vorliegende Version mag meinen Compiler nicht, und bei allen Compilereinstellungen (die er braucht, um den Code korrekt zu interpretieren) die ich ausprobiert habe, beendet er sich in den Qt-Headern mit der Meldung - für diesen Compiler nicht geeignet :-( ) -
liegt auch kein Memory-Leak vor, d.h. alles wird (zumindest beim Beenden des Programms) sauber abgeräumt.

Gruss
Tilman

harry_m
Beiträge: 74
Registriert: 26. April 2010 23:16

Re: Kontinuierlich anwachsender Speicherbedarf

Beitrag von harry_m » 26. Oktober 2012 21:09

Ich finde es gut, dass darüber gesprochen wird.

Diejenigen, die alles wissen und können verirren sich ganz offensichtlich selten hierher. Komplizierte Fragen bleiben meistens eher unbeantwortet... Und für Anfänger und weniger erfahrene kann der eine oder andere Satz ein guter Hinweis sein.
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)

franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Re: Kontinuierlich anwachsender Speicherbedarf

Beitrag von franzf » 26. Oktober 2012 21:59

valgrind --tool=massif mein_programm
Das auswerten, am besten gleich mit massif-visualizer. Das zeigt die größten "Speicherfresser".
Dann sieht man es entweder gleich - wenn nicht mit gdb in den Funktionen breakpoints setzen und backtrace geben lassen.

Zum Spielen hier ein kleiner Test:

Code: Alles auswählen

#include <QtCore/QObject>
#include <QtCore/QVector>

class Obj : public QObject
{
public:
    void addOneMore() {
        new QObject(this);
    }
};

class Clean {
    QVector<QString*> strings;
public:
    void addString(QString str) { strings.append(new QString(str)); }
    ~Clean() {
        qDeleteAll(strings);
    }
};
    

int main() {
    Obj o;
    Clean c;
    for(int i=0; i<100000; ++i) {
        o.addOneMore();
        c.addString(QString::number(i));
    }
}

Code: Alles auswählen

==28442== LEAK SUMMARY:
==28442==    definitely lost: 0 bytes in 0 blocks
==28442==    indirectly lost: 0 bytes in 0 blocks
==28442==      possibly lost: 0 bytes in 0 blocks
addOneMore + addString sind "ganz oben" - darauf dann eine breakpoint setzen + bt anzeigen lassen. Ist zwar mühsam sollte aber zum Ziel führen.

Tilman Räger
Beiträge: 189
Registriert: 6. Juni 2007 15:23
Wohnort: Göttingen

Re: Kontinuierlich anwachsender Speicherbedarf

Beitrag von Tilman Räger » 27. Oktober 2012 23:28

Hallo,
Beitragvon franzf » Fr Okt 26, 2012 20:59
valgrind --tool=massif mein_programm
Bin ich mit dieser Option in der Lage, solche Probleme aufzudecken, also das ich von QObject abgeleitete Klassen mit Parent erzeuge und dann vergesse? Ich bin bisher noch nicht dazu gekommen, Dein Beispiel daraufhin auszuprobieren.

Ansonsten sollte es ja möglich sein, alle Objekte, die mit Parent erzeugt werden (da keine rekursiven Aufrufe vorkommen, dürfte es sich ja nur um Objekte handeln, die mit new erzeugt werden und nicht mehr mit delete weggeräumt werden, da sie einen Parent haben, jedoch beim Löschen dieses Parents mit weggeräumt werden. Ersetze ich den Parent durch NULL müsste ich ein paar niedliche MemoryLeaks haben.

Korrigiert mich bitte, wenn ich daneben liege :-) !

Darüber hinaus hat sich Valgrind (schon in der Standard-Einstellung bei Aufruf über den QtCreator) als anscheinend gründlicher als dieser 'Visual Leak Detektor' herausgestellt und mir, nachdem ich das Programm unter Linux wieder am Laufen hatte, auch noch eine ganze Latte an Problemen um die Ohren gehauen. Da werd' ich ab morgen erst einmal einiges zu tun haben :-)

Gruss
Tilman (Räger)

RHBaum
Beiträge: 1436
Registriert: 17. Juni 2005 09:58

Re: Kontinuierlich anwachsender Speicherbedarf

Beitrag von RHBaum » 29. Oktober 2012 13:20

also das ich von QObject abgeleitete Klassen mit Parent erzeuge und dann vergesse?
Diesen mechanismus solltest nicht in Frage stellen :-) Oder Du solltest Qt nicht benutzen ...
Um zu checken ob QT alles sauber aufraeumt, solltest dein qApp mal auslaufen lassen ....

Code: Alles auswählen

int main()
{
    /// Aufruf von QT zeugs in eigenen Block 
    {
        QApplication a(argc, argv);
	/// a.setStyle(new QWindowsXPStyle);
	a.setStyle(new QWindowsVistaStyle);
	a.setOrganizationName("My Organization");
	a.setApplicationName("My Application");
	myMeinWindow w;
	w.show();
	return a.exec();
    }
    /// Testcode 
    /// Wenn Mainwindow geschlossen kommst hier rein und Qt muesste theorethisch entladen sein ... 
}
Noch 2 Anmerkungen:
Verlass Dich nicht allzusehr auf die Anzeige Deines OS !
zwischen deinem new / delete sitzen oft 2 Speichermanager ... der vom OS, der von der c++ runtime, oftmals sogar noch nen 3ter .... die alle koennen das freigeben von Speicher wegens Optimierungszwecke verzögern / verhindern.
Die Speicher API von Windows z.b. ist etwas komplexer als nur gib Speicher, da hasst speicher zurueck ^^ Da kann man Prioritaeten einstellen und windows kann einen benachrichten, das es etwas knapper mit Speicher langsam wird, und man weniger optimistisch allokieren soll ... selbst wenn du unter c++ dich darum nicht scherst, deine Speichermanager tun es :-)
Also kann es durchaus sein, dass dein Speicher den scho lange freigegeben hasst, bis zum programmende vom System als verwendet angesehen wird, weil windows eh meint es hat speicher im überfluss :-)

Mit einem meiner Progs hab ich mal etwas ausführlicher das Speicherverhalten gestestet ....
und da kommen ganz komische Phaenomene:
Unter windows 7 32 mit 4GB RAM braucht mein prog tendentiell die Haelfte, als wie unter windows 7 64 mit 20 GB
Als 64bit Anwendung kompiliert greift es nochmal ordentlich mehr zu .... da kriegt man fast graue Haare beim zuschauen ^^
(Visual Studio Standard 64 bit Modell, also nur Zeiger werden auf 64 bit breite expandiert, und soviele zeiger kann ich gar ned verwenden ^^)
Aber startet man paralell nen anderes 64 bit prog was expliziet ordentlich speicher allokiert, dann sackt der Speicherverbrauch vom 1 Prog sofort zusammen ....

Wenn Dir die Kontrolle des Speicherverbrauch so wichtig ist ... meide QT !
QT verwendet aus caching / Optimierungsgruenden ne Menge Speicher ... der globalen Objecten zugeordnet ist.
Dieser wird sicher / endgueltig erst freigegeben, nachem deine main durchgelaufen ist (globale Variablen / Scope) ...

Qt ist toll, als das was es ist ... ein GUI-Framework.
fuer andere Dinge (Datenhaltung, Business-Logik etc) würd ichs einfach ned nehmen ....

Ciao ....

Tilman Räger
Beiträge: 189
Registriert: 6. Juni 2007 15:23
Wohnort: Göttingen

Re: Kontinuierlich anwachsender Speicherbedarf

Beitrag von Tilman Räger » 30. Oktober 2012 19:58

Hallo,

nachdem ich die Anwendung noch ein wenig (!) optimiert habe und mit den genannten Tools drauf losgegangen bin, hat sich das Verhalten anscheinend endlich stabilisiert. Wenn ich mir den Speicherbedarf des Programms über /proc/<PID>/status bzw. statm unter Linux bzw. über die entsprechende API unter Windows ausgeben lasse, bleibt er bei Linux nun stabil, bei Windows steigt er noch langsam (möglicherweise auch nur bis zu einem Grenzwert an.
Was genau jetzt dafür verantwortlich war, kann ich nicht sagen - potentielle Memory-Leaks meldet er mir zwar - aber alle tief unten aus den Qt-Bibliotheken, und dort auch von einzelnen Objekten, die zu Beginn erzeugt und beim herunterfahren gelöscht werden. Absolut nichts cyclisches, was ein kontinuierliches Anwachsen erklären würde.
Ein Versuch, alle von mir erzeugten Objekte (soweit von mir erstellte Klassen) mit entsprechenden Traces in Kon- und Destruktor zu versehen, ergab das selbe Resultat.

Allen, die mir bei dem Problem geholfen haben, daher vielen Dank. Und weiter zum nächsten Problem, aber, da völlig anderes Thema in einem neuen Thread :-)

Tilman (Räger)

harry_m
Beiträge: 74
Registriert: 26. April 2010 23:16

Re: Kontinuierlich anwachsender Speicherbedarf

Beitrag von harry_m » 9. November 2012 19:37

RHBaum hat geschrieben:
also das ich von QObject abgeleitete Klassen mit Parent erzeuge und dann vergesse?

Mit einem meiner Progs hab ich mal etwas ausführlicher das Speicherverhalten gestestet ....
und da kommen ganz komische Phaenomene:
Unter windows 7 32 mit 4GB RAM braucht mein prog tendentiell die Haelfte, als wie unter windows 7 64 mit 20 GB
Als 64bit Anwendung kompiliert greift es nochmal ordentlich mehr zu .... da kriegt man fast graue Haare beim zuschauen ^^
(Visual Studio Standard 64 bit Modell, also nur Zeiger werden auf 64 bit breite expandiert, und soviele zeiger kann ich gar ned verwenden ^^)
Aber startet man paralell nen anderes 64 bit prog was expliziet ordentlich speicher allokiert, dann sackt der Speicherverbrauch vom 1 Prog sofort zusammen ....

Wenn Dir die Kontrolle des Speicherverbrauch so wichtig ist ... meide QT !
QT verwendet aus caching / Optimierungsgruenden ne Menge Speicher ... der globalen Objecten zugeordnet ist.
Dieser wird sicher / endgueltig erst freigegeben, nachem deine main durchgelaufen ist (globale Variablen / Scope) ...

Qt ist toll, als das was es ist ... ein GUI-Framework.
fuer andere Dinge (Datenhaltung, Business-Logik etc) würd ichs einfach ned nehmen ....

Ciao ....
Ich habe diesen Beitrag jetzt insgesamt drei mal gelesen und habe zwischendurch nachgedacht...

An sich alles richtig, aber ein Paar Fragen hätte ich schon...

1. Speicherbedarf der Applikation, abhängig von dem aktuellen Speicherstand... (...Aber startet man paralell nen anderes 64 bit prog was expliziet ordentlich speicher allokiert, dann sackt der Speicherverbrauch vom 1 Prog sofort zusammen .... ) Warum ist das schlimm? Es ist doch genau das, was sinnvoll ist: wenn der Speicher sagen wir zu 90% belegt ist, muss scharf kalkuliert werden. Aber wenn 90% frei sind: super! - Dann lassen wir die wenige laufenden Applikationen so viel Speicher nutzen, wie sie es vielleicht im "schlimmsten" Fall wollen! Wo ist das Problem? Wenn ein eingefleischter Windows-Benutzer zum ersten Mal die Speicheranzeige unter Linux ansieht, fällt ihm immer die Kinnlade herab: "Wieso braucht Linux so viel Speicher?!!! Da braucht Windows ja nur ein Drittel davon!!!" Diese Frage habe ich auch mal gestellt und bekam die Antwort, dass es unter Linux für die Verbesserung der Performance gemacht wird. (Wobei Windows sich schon seit Jahren der "Preload"-Methode bedient...) Wurde dieser Mechanismus nicht als der Grund genannt, warum Linux-Systeme vom Speicherausbau viel mehr profitieren, als die mit Windows?!

2. ...Wenn Dir die Kontrolle des Speicherverbrauch so wichtig ist ... meide QT ! ....
Diesen Satz kann ich nicht ohne Weiteres nachvollziehen. Qt ist doch nur ein Framework und setzt auf einen Compiler auf: unter Windows z.B. auf MinGW und unter Linux auf gcc. Die Speicherverwaltung soll demzufolge zum größten Teil im Betriebssystem und zum kleineren durch den Compiler bestimmt werden. Oder greift Qt wirklich so tief in die Trickkiste der Speicherverwaltung? Das kann ich mir irgendwie nicht vorstellen: denn dann würde man im Qt eine Menge Plattform abhängiger Module unterbringen müssen.
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 » 26. November 2012 19:14

Warum ist das schlimm?
Nein, es ist überhaupt nicht schlimm ! Sondern nur ein Indiz, das man sich auf die Anzeige des BS für den Speicherverbrauch nicht verlassen sollte ... bzw der speicherverbrauch vom BS her nicht fest ist sondern von anderen Groessen auch abhaengig ist .
2. ...Wenn Dir die Kontrolle des Speicherverbrauch so wichtig ist ... meide QT ! ....
Diesen Satz kann ich nicht ohne Weiteres nachvollziehen. Qt ist doch nur ein Framework und setzt auf einen Compiler auf: unter Windows z.B. auf MinGW und unter Linux auf gcc. Die Speicherverwaltung soll demzufolge zum größten Teil im Betriebssystem und zum kleineren durch den Compiler bestimmt werden. Oder greift Qt wirklich so tief in die Trickkiste der Speicherverwaltung? Das kann ich mir irgendwie nicht vorstellen: denn dann würde man im Qt eine Menge Plattform abhängiger Module unterbringen müssen.
Nein, qt greift da gar nicht ein .... es deligiert das new genau so an die c++ runtime wie jedes andere c++ Programm.

Der Grosse unterschied ist der Programmierstil und da eigentlich die QObject Hirarchie.
"Normal" Allokiert man per new speicher fuer ein neues (Q)Object ....
Löscht man es wenn man es wieder braucht ? Meistens nicht, sondern man gibt ihm den Parent (QObject-Zeiger) mit. D.h. das teil wird automatisch gelöscht, wenn der parent zerstört wird.
Meist löscht man, wenn man QObejcte schon mal manuell zerstören will, nicht mit "delete" sondern mit QObject::deleteLater(), weil man der QObject hirarchie noch Zeit geben sollte, Events die in der Queue stehen und dem Object zugeordnet sind, abarbeiten zu können !
D.h. das Ding löscht automatisch und nicht zu den von dir getriggerten Zeitpunkten. Das ist wie ein Garbage Collector, nur mit doch noch etwas mehr Vorraussehbarkeit :-)

In 99% der Faelle aller Programme ist das eh ok :-) sowieso wenn ne GUI mit reinspielt ...
Desktopanwendungen muessen bissi speicher haben, damit die App ueberhaupt atmen kann ^^
Selbst modernere Smartphones haben genug speicher, als das sowas kritisch werden könnte.
Von meiner Seite Fällt das alles in die Kategorie: "Speicher ? kein problem, hab ich genug, muss ich eh genug haben ..."

Jetzt stell dir vor Du machst eine Interpretation von gestraemten Daten, mit Objecten, deren eigentliche Daten (auf den Strom) nur wenige Bytes gross sind.
Dann noch die Vorstellung, das so nen Datenstrom in Echtzeit analysiert werden soll, und die bitraten im extremfall bis 8 Mbit/s erreichen koennen.
Dann wuerde Dir so ne Speicherallokation das "genick" brechen :-)
Oder stell dir vor, Du musst zigtausende von 3d Objecten berechnen und in echtzeit darstellen ...
Oder stell dir ne DB vor, die mehrere millionen transaktionen pro Sek serialisieren muss ....
Wenn Dir die Kontrolle des Speicherverbrauch so wichtig ist

Bei solchen Anwendungsfällen wird sie definitiv wichtig !

und da wuerde aber auch keiner auf die Idee kommen, dafuer Qt einzusetzen, also zumindest nicht fuer die "basisfunktionalitaet". Tools und Visualisieren dagegen machts schon wieder mehr Sinn ...

Ciao ....

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

Re: Kontinuierlich anwachsender Speicherbedarf

Beitrag von Markus » 27. November 2012 12:28

RHBaum hat geschrieben: [...]und da wuerde aber auch keiner auf die Idee kommen, dafuer Qt einzusetzen, also zumindest nicht fuer die "basisfunktionalitaet".[...]
Und was würde man für diese "Basisfunktionalität" einsetzen?

Tilman Räger
Beiträge: 189
Registriert: 6. Juni 2007 15:23
Wohnort: Göttingen

Re: Kontinuierlich anwachsender Speicherbedarf

Beitrag von Tilman Räger » 27. November 2012 12:38

Hallo,

um noch einmal zum ursprünglichen Grund des Thread zurückzukommen:

Meine Anwendung hat sich inzwischen unter Linux als absolut stabil erwiesen, was den Speicherverbrauch angeht (andere Aspekte leider noch nicht so 100%ig :-) ) - nur unter Windows wächst der Speicher nach wie vor mässig aber regelmässig. (von mir stammende) Quellcode ist zu ca. 98 % identisch, die unterschiedlichen Teile werden nicht cyclisch ausgeführt, dürften also wenn dann einmalige MemoryLeaks hinterlassen. Hauptunterschied ist, das ich unter Linux mit MySQL arbeite unter Windows meist mit ODBC-Datenbanken. Ist es möglich, dass der ODBC-Treiber für dieses Anwachsen des Speichers verantwortlich ist. Mein Kunde meinte, er hätte da etwas läuten hören. Vielleicht hat ja jemand damit schon erfahrungen gemacht?

Gruss
Tilman Räger

Antworten