Speicher wird nicht mehr freigegeben ?!?!
-
Hallo,
ich habe dein Testprogramm von Seite 1 mal bei mir laufen lassen. Bei mir wird
kein Speicher festgehalten, er steigt bei mir nicht mal auf 50MB. Ich habe
konstant knapp 8MB RES, das wars auch schon.Bei deiner ersten geposteten Aenderung, sinkt die RES auf ca. 3,7MB. Wieder
werden keine 50MB bis Programmende gehalten.Dann habe ich deine naechst geposteten main-Funktionen ausprobiert und auch
Braunsteins Code eingebaut. In allen Faellen hat sich an meinem Speicher-
verbrauch nichts geaendert.In allen deinen 3 Programmen, kann ich das Problem auf meinem System
nicht nachvollziehen.Aber wie die anderen bereits gesagt haben:
Speicher ist etwas, was das OS dem Programm zuordnet. Wenn du Speicher wieder
freigibst, heisst das nicht, dass das OS diese Zuordnung direkt wieder
aufhebt. Um evtl. weiteren Speicheranforderungen schnell Rechnung zu tragen,
wird es, vor allem wenn es erkennt, dass du sehr haeufig Speicher anforderst,
diese Zuordnung nicht aufheben. Dir bleibt dann der Speicher zugeordnet und
daran kannst du auch erstmal nichts dran aendern.Ob es sich bei dieser Zuordnung nun um mehr oder weniger als 50MB handelt,
ist eine Entscheidung, welche das OS faellt und von dir nicht beeinflussbar
ist.Das System mit welchem ich testen kann:
FreeBSD 7.0-BETA4.
gruss
v R
-
virtuell Realisticer schrieb:
ich habe dein Testprogramm von Seite 1 mal bei mir laufen lassen. Bei mir wird ein Speicher festgehalten, er steigt bei mir nicht mal auf 50MB. Ich habe konstant knapp 8MB RES, das wars auch schon.
Bei deiner ersten geposteten Aenderung, sinkt die RES auf ca. 3,7MB. Wieder werden keine 50MB bis Programmende gehalten.
DANKE das du gestestet hast!
also das beispiel auf der ersten seite ist eigentlich dank dem swap-trick für mich gelöst. aber anders sieht es zb. aus mit dem 2. und 3. beispiel in meinem letzten posting. hast du dort auch überall deine freigaben (bin mir nicht sicher ob du in deinem beitrag diese beispiele dann meinst) ?
virtuell Realisticer schrieb:
Aber wie die anderen bereits gesagt haben:
Speicher ist etwas, was das OS dem Programm zuordnet. Wenn du Speicher wieder freigibst, heisst das nicht, dass das OS diese Zuordnung direkt wieder aufhebt. Um evtl. weiteren Speicheranforderungen schnell Rechnung zu tragen, wird es, vor allem wenn es erkennt, dass du sehr haeufig Speicher anforderst, diese Zuordnung nicht aufheben. Dir bleibt dann der Speicher zugeordnet und daran kannst du auch erstmal nichts dran aendern.solange dieser nur mir zugeordnet bleibt, wenn keine speichernot herscht, kann ich mich damit abfinden, jedoch sieht das anders aus, wenn ich einen zweiten dienst starte und der legt mir eben statt 10.000 vector elementen 1.000.000 an, dann geht der maschine der speicher aus und bevor der speicher ausgeht, sollte doch der freie speicher von meinem testprogramm verwendet/abgezogen werden oder? leider hat mein test damals das nicht gemacht.
virtuell Realisticer schrieb:
Ob es sich bei dieser Zuordnung nun um mehr oder weniger als 50MB handelt, ist eine Entscheidung, welche das OS faellt und von dir nicht beeinflussbar ist.
die 50MB sind nur ein beispiel, weil verändere ich die define-werte, dann verändert sich auch das verhalten wieviel speicher am ende noch übrig bleibt.
virtuell Realisticer schrieb:
FreeBSD 7.0-BETA4.
ich habe auf einem fedora core 2, fedora core 5, ubuntu 7.1, suse 8.1 getestet, es wurden nirgends updates gemacht und hatte überall die gleichen "probleme"
-
Hallo,
taff schrieb:
virtuell Realisticer schrieb:
ich habe dein Testprogramm von Seite 1 mal bei mir laufen lassen. Bei mir wird ein Speicher festgehalten, er steigt bei mir nicht mal auf 50MB. Ich habe konstant knapp 8MB RES, das wars auch schon.
Bei deiner ersten geposteten Aenderung, sinkt die RES auf ca. 3,7MB. Wieder werden keine 50MB bis Programmende gehalten.
DANKE das du gestestet hast!
also das beispiel auf der ersten seite ist eigentlich dank dem swap-trick für mich gelöst. aber anders sieht es zb. aus mit dem 2. und 3. beispiel in meinem letzten posting. hast du dort auch überall deine freigaben (bin mir nicht sicher ob du in deinem beitrag diese beispiele dann meinst) ?
Die von dir zuletzt geposteten bringen folgendes Resultat:
Programm 1: Zugesicherter Speicher: 3660K
Programm 2: Zugesicherter Speicher: 3704K
Programm 3: Zugesicherter Speicher: 3700Kvirtuell Realisticer schrieb:
Aber wie die anderen bereits gesagt haben:
Speicher ist etwas, was das OS dem Programm zuordnet. Wenn du Speicher wieder freigibst, heisst das nicht, dass das OS diese Zuordnung direkt wieder aufhebt. Um evtl. weiteren Speicheranforderungen schnell Rechnung zu tragen, wird es, vor allem wenn es erkennt, dass du sehr haeufig Speicher anforderst, diese Zuordnung nicht aufheben. Dir bleibt dann der Speicher zugeordnet und daran kannst du auch erstmal nichts dran aendern.solange dieser nur mir zugeordnet bleibt, wenn keine speichernot herscht, kann ich mich damit abfinden, jedoch sieht das anders aus, wenn ich einen zweiten dienst starte und der legt mir eben statt 10.000 vector elementen 1.000.000 an, dann geht der maschine der speicher aus und bevor der speicher ausgeht, sollte doch der freie speicher von meinem testprogramm verwendet/abgezogen werden oder? leider hat mein test damals das nicht gemacht.
Ja das ist merkwuerdig. Das ist bei mir gar nicht der Fall.
virtuell Realisticer schrieb:
Ob es sich bei dieser Zuordnung nun um mehr oder weniger als 50MB handelt, ist eine Entscheidung, welche das OS faellt und von dir nicht beeinflussbar ist.
die 50MB sind nur ein beispiel, weil verändere ich die define-werte, dann verändert sich auch das verhalten wieviel speicher am ende noch übrig bleibt.
Ja da hast du allerdings auch recht.
virtuell Realisticer schrieb:
FreeBSD 7.0-BETA4.
ich habe auf einem fedora core 2, fedora core 5, ubuntu 7.1, suse 8.1 getestet, es wurden nirgends updates gemacht und hatte überall die gleichen "probleme"
Welche Kernelversion nutzt du?
gruss
v R
-
virtuell Realisticer schrieb:
Die von dir zuletzt geposteten bringen folgendes Resultat:
Programm 1: Zugesicherter Speicher: 3660K
Programm 2: Zugesicherter Speicher: 3704K
Programm 3: Zugesicherter Speicher: 3700Kbei beispiel 1 und beispiel 2 geht am ende mein speicherverbrauch auf 1052K zurück
virtuell Realisticer schrieb:
Welche Kernelversion nutzt du?
beim suse habe ich 2.4.19 und dort habe ich mir mittels kdevelop ein auto-make file erstellen lassen, damit auch mal vom firmen internen standard-makefile löse usw. ansonsten reichen die anderen version von 2.6.5 bis 2.6.20
-
taff schrieb:
virtuell Realisticer schrieb:
Die von dir zuletzt geposteten bringen folgendes Resultat:
Programm 1: Zugesicherter Speicher: 3660K
Programm 2: Zugesicherter Speicher: 3704K
Programm 3: Zugesicherter Speicher: 3700Kbei beispiel 1 und beispiel 2 geht am ende mein speicherverbrauch auf 1052K zurück
Naja wie gesagt, der zugesicherte Speicher hat wenig aussagekraft.
virtuell Realisticer schrieb:
Welche Kernelversion nutzt du?
beim suse habe ich 2.4.19 und dort habe ich mir mittels kdevelop ein auto-make file erstellen lassen, damit auch mal vom firmen internen standard-makefile löse usw. ansonsten reichen die anderen version von 2.6.5 bis 2.6.20
Ein Linux hab ich leider nicht hier, wenn ich mal wieder zu meinem Nebenjob
gehe, werd ich dort mal die Testprogramme auf einigen Linuxkisten laufen
lassen.gruss
v R
-
virtuell Realisticer schrieb:
Naja wie gesagt, der zugesicherte Speicher hat wenig aussagekraft
das sowieso, aber danke für deine bemühungen.
gestern abend habe ich noch einwenig weitergetestet und mir mal folgendes angesehen: was passiert, wenn ich nach dem löschen meines vectors wieder weitere datenelemente anlege und lösche und war dann doch wieder mal überrascht und auf mich selbst verärgert.
ich habe ganz am ende (also vor der while-schleife mit dem sleep) folgendes eingefügt:
while(0) { sleep(3); Data* arr[BUFFER_ADDS]; for(int i=0; i<1; i++) { arr[i] = new Data(); arr[i]->Set(buffer); } for(int i=0; i<1; i++) // lösche ich meinen buffer hier nicht, dann wird auch der andere schon reservierte buffer nicht "total" freigegeben delete arr[i]; }
das ergebnis ist:
- der speicher reduziert sich auf 11MB
- mache ich von diesem neu angelgten buffer kein delete, wird der speicher deshalb auch nicht weniger.
- der nun neu angelegte speicher behält den "status" reserviert obwohl alles freigegeben wurde -> somit weitere 11MB die eigentlich frei wären und trotzdem mir zugeordnet werden.
getrieben mit diesen erkenntnissen habe ich nun folgende tests durchgeführt und den obigen code durch diesen hier ersetzt:
if(1) { double d1(0.0); double d2(0.0); int i(1); char buf1[10]; memset(buf1, 'A', 10); buf1[10]= '/0'; string str; str.append(10,'a'); str.clear(); }
es gibt hier keinen erfolg. ich habe das ganze in einen block geschrieben, damit meine variablen im stack auch wieder zerstört werden.
if(1) { double d1(0.0); double d2(0.0); int i(1); char buf1[10]; memset(buf1, 'A', 1000); buf1[10]= '/0'; string str; str.append(1000,'a'); str.clear(); }
erfolg ist da! speicher wird wieder zu meiner zufriedenheit freigegeben. und habe am ende 1056KB zugewiesenen speicher. wobei ich wieder ausfindig machen konnte, dass der hier angelegte speicher mir wieder nach dem blockende wieder "reserviert" bleibt. was ich hier noch hinterfragen möchte, warum muss eine gewisse speichergröße überschritten werden, damit der mir zuvor zugeordnete freie speicher freigegeben wird?
eigentlich könnte man nun sagen, mein problem ist gelöst - EIGENTLICH.
wenn man nun so wie ich es aber benötige, am anfang viele daten einlese, später zb. in diesem array jeden zweiten vector zerstöre und mit den dadurch entstandenen daten arbeite und dann außer find-methoden aufrufen nicht mehr viel mache, sprich keine weiteren großen speicherblöche mehr anlege, schleppe ich freien zugeordneten speicher mit, welchen leider keine andere application mehr abzweigen kann, wenn speichernot herscht.
-
Nabend,
taff schrieb:
virtuell Realisticer schrieb:
Naja wie gesagt, der zugesicherte Speicher hat wenig aussagekraft
das sowieso, aber danke für deine bemühungen.
gestern abend habe ich noch einwenig weitergetestet und mir mal folgendes angesehen: was passiert, wenn ich nach dem löschen meines vectors wieder weitere datenelemente anlege und lösche und war dann doch wieder mal überrascht und auf mich selbst verärgert.
ich habe ganz am ende (also vor der while-schleife mit dem sleep) folgendes eingefügt:
while(0) { sleep(3); Data* arr[BUFFER_ADDS]; for(int i=0; i<1; i++) { arr[i] = new Data(); arr[i]->Set(buffer); } for(int i=0; i<1; i++) // lösche ich meinen buffer hier nicht, dann wird auch der andere schon reservierte buffer nicht "total" freigegeben delete arr[i]; }
das ergebnis ist:
- der speicher reduziert sich auf 11MB
- mache ich von diesem neu angelgten buffer kein delete, wird der speicher deshalb auch nicht weniger.
Naja, das ist ja klar. Von dir reservierter Speicher muss auch wieder
freigegeben werden. Alternativ dazu kannst du boost::ptr_vector verwenden.- der nun neu angelegte speicher behält den "status" reserviert obwohl alles freigegeben wurde -> somit weitere 11MB die eigentlich frei wären und trotzdem mir zugeordnet werden.
Nur damit ich dich nicht falsch verstehe:
Zunaechst hast du den alten Speicherplatz freigegeben und dann den neuen
Puffer reserviert. Dann hast du diesen wieder freigegeben und der Speicher-
platz bleibt deiner Anwendung zugeordnet.Dieses Verhalten ist zunaechst einmal nicht weiter schlimm.
Hast du nach wie vor das Problem, dass auch bei Speicherknappheit dieser
Speicherplatz fuer dein Programm erhalten bleibt?getrieben mit diesen erkenntnissen habe ich nun folgende tests durchgeführt und den obigen code durch diesen hier ersetzt:
if(1) { double d1(0.0); double d2(0.0); int i(1); char buf1[10]; memset(buf1, 'A', 10); buf1[10]= '/0'; string str; str.append(10,'a'); str.clear(); }
es gibt hier keinen erfolg. ich habe das ganze in einen block geschrieben, damit meine variablen im stack auch wieder zerstört werden.
Was dafuer sprechen koennte, dass der Stack noch nicht verkleinert worden
ist. Ein Hinweis von Freundlich (aus dem irc):Freundlich schrieb:
17:22 <Freundlich> Es kann sehr gut sein, dass da nirgendwo was gel"oscht wird.
17:23 <Freundlich> string nutzt normalerweise COW oder small-buffer-optimization.
17:23 <Freundlich> clear l"oscht nichts.
17:23 <Freundlich> Also wird da nichts freigegeben.if(1) { double d1(0.0); double d2(0.0); int i(1); char buf1[10]; memset(buf1, 'A', 1000); buf1[10]= '/0'; string str; str.append(1000,'a'); str.clear(); }
erfolg ist da! speicher wird wieder zu meiner zufriedenheit freigegeben. und habe am ende 1056KB zugewiesenen speicher. wobei ich wieder ausfindig machen konnte, dass der hier angelegte speicher mir wieder nach dem blockende wieder "reserviert" bleibt. was ich hier noch hinterfragen möchte, warum muss eine gewisse speichergröße überschritten werden, damit der mir zuvor zugeordnete freie speicher freigegeben wird?
buf1 hat nur 10 Elemente!
eigentlich könnte man nun sagen, mein problem ist gelöst - EIGENTLICH.
wenn man nun so wie ich es aber benötige, am anfang viele daten einlese, später zb. in diesem array jeden zweiten vector zerstöre und mit den dadurch entstandenen daten arbeite und dann außer find-methoden aufrufen nicht mehr viel mache, sprich keine weiteren großen speicherblöche mehr anlege, schleppe ich freien zugeordneten speicher mit, welchen leider keine andere application mehr abzweigen kann, wenn speichernot herscht.Wie gesagt, dieses Verhalten ist mir schleierhaft und ich kann es auf meinem
System nicht nachvollziehen. Wenn es dir nicht zuviel Aufwand ist, koenntest
du mal auf eines der Systeme einen aktuellen Kernel kompilieren und den
Test wiederholen.Noch ein kleiner Hinweis von Freundlich, der sich das auch mal angeschaut
hat:Bei deinem dritten geposteten Programm musst du am schluss delete[] aufrufen
und nicht delete, du hast schliesslich ein Array allokiert.gruss
v R
-
guten morgen!
virtuell Realisticer schrieb:
Naja, das ist ja klar. Von dir reservierter Speicher muss auch wieder
freigegeben werden. Alternativ dazu kannst du boost::ptr_vector verwenden.meine überlegung war folgende, wenn ich nun vor dem while wo der vector+array schon freigegeben wurde, einfach was anlege und ich das neu angelegte nicht freigebe, ob ich hier auch schon veränderungen meines freigegeben und trotzdem noch zugewiesenen speicher von vorhin habe. wie gesagt die neuen variablen müssen auch freigegeben werden, dann kann sich erst was auswirken.
virtuell Realisticer schrieb:
Nur damit ich dich nicht falsch verstehe:
Zunaechst hast du den alten Speicherplatz freigegeben und dann den neuen
Puffer reserviert. Dann hast du diesen wieder freigegeben und der Speicher-
platz bleibt deiner Anwendung zugeordnet.Dieses Verhalten ist zunaechst einmal nicht weiter schlimm.
Hast du nach wie vor das Problem, dass auch bei Speicherknappheit dieser
Speicherplatz fuer dein Programm erhalten bleibt?genau so ist es!
zuerst habe ich ~50mb freigegebenen mir zugeordneten speicher und dann sind es 11mb freigegebener zugeordneter speicher, wobei hier auch gilt, lege ich mehr speicher an, dann könnten es auch am ende 100mb sein. starte ich mein testprogramm, welches einfach nur speicher belegt wird, kann dieses auch nicht auf den freiggegeben zugeordneten speicher zugreifen.virtuell Realisticer schrieb:
buf1 hat nur 10 Elemente!
sorry mein fehler hier beim posting, habe die 1000-elemente version hier zuerst reinkopiert und dann vergessen dies beim memset richtig zu stellen, also getestet wurde natürlich mit der 10elemente version.
virtuell Realisticer schrieb:
Noch ein kleiner Hinweis von Freundlich, der sich das auch mal angeschaut
hat:Bei deinem dritten geposteten Programm musst du am schluss delete[] aufrufen
und nicht delete, du hast schliesslich ein Array allokiert.ups stimmt, danke! die buffer-variable muss ich natürlich so freigegeben, wobei wie gerade getestet dies keine weiteren auswirkungen hat und der schon freigegebene und mir zurgeordnete speicher trotzdem nachdem
delete[] buffer;
nun total freigegeben wird. (war vorher mittels delete ohne [] auch so)
werde mir am wochenende eine linux umgebung auf den neuesten stand der dinge bringen, also kernel stable version 2.6.23.9
-
Hallo,
ja das waere sehr interessant, wenn du das machst und mal postest, ob sich
dann etwas an dem Verhalten aendert.Fuer mich ist es leider schwer da nach Loesungen zu suchen, da bei mir dieses
Problem gar nicht auftritt, ich kann also nur Vermutungen anstellen :).gruss
v R
-
so, mit verspätung aber doch noch, kann ich nun "infos" zu den tests mit dem 2.6.23.9 kernel posten.
getestet wurde mittels vmware, fedora core 8, kdevelop und eben dem aktuellen stable kernelkurz und bündig es ändert sich nichts!
ich habe die 3 beispiele von der vorseite ausprobiert, sowie mit der zusätzlichen speicher reservierung und freigabe vor der while-sleep schleife wie auf dieser seite schon besprochen - das verhalten bleibt gleich!
zusätzlich habe ich wieder bei einer version wo mir 42mb übrig geblieben sind einen anderen service gestartet der mir einfach speicher frisst, leider wurden auch hier wieder die 42mb bei speichernot nicht freigegeben!
-
Vor langer langer Zeit hatte ich Probleme mit der Speicherfreigabe und da ich vor kurzem auf eine mögliche Lösung gestoßen bin, möchte ich die hier der vollständigkeithalber die auch veröffentlichen:
Mit diesem Befehl wird wieder alles "richtig" freigegeben.
malloc_trim(0);
Angeblich kann man mittels
int mallopt(int param, int value);
das ganze nach seinen bedürfnissen einstellen.
Falls es jemanden gibt der mehr darüber weiß, der darf ruhig dies auch kund tun
-
Ich habe deinen letzten Beitrag nicht umsonst gelöscht. Niemand wird sich 6 Seiten eines 6 Jahre alten Threads durchlesen und niemand weiß mehr, worum es geht!
Wenn du Fragen hast, dann mach einen neuen Thread auf, in dem du dein Problem vollständig erklärst, so dass man auch ohne Hintergrundwissen über antike Forengeschichte deine Frage verstehen kann. Sei dir auch sicher, dass du im richtigen Forum fragst, malloc_trim und mallopt sind Linuxfunktionen.