Autor Beitrag
Terra23
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 872

Win 8
Delphi 7
BeitragVerfasst: Do 11.10.12 17:48 
Hi Leute!

Leider habe ich im WWW nichts gefunden, was mich vollends zufriedenstellt, daher dieser Thread.

Ich habe ein sehr umfangreiches Programm geschrieben (einen Decklisteneditor für ein Sammelkartenspiel) und würde gern wissen, ob ich, wenn das Programm geschlossen wird, den Speicher, den es innerhalb von Windows für sich beansprucht, wieder freigeben muss und wenn ja, wie ich das tun kann.

Ich habe gestern das Programm ein paar Mal starten müssen um gewisse Funktionen zu testen und hatte das Gefühl, dass mein PC, nachdem ich ihn heute aus dem Standby-Modus geholt hatte (also beim Laptop den Deckel wieder geöffnet), dass er total langsam ist und ein Neustart brachte dann die erhoffte (gefühlte) Verbesserung.
Es kann natürlich auch sein, dass es daran liegt, dass der Laptop schon 6-7 Jahre auf dem Buckel hat und so langsam den Geist aufgibt.

Ich habe, während mein Programm läuft, keine Speicherauslastung oder dergleichen im Task-Manager feststellen können und Dinge wie MemoryStreams, die ich im laufenden Programm erzeuge, werden auch ordnungsgemäß wieder freigegeben. Objekte erzeuge ich während des Programms eigentlich keine.

Ich wäre euch dankbar, wenn mir jemand kurz mitteilen könnte, ob und wie ich Speicher beim Beenden des Programms freiegeben kann / muss.

Gruß,

Terra


Moderiert von user profile iconNarses: Topic aus Sonstiges (Delphi) verschoben am Do 11.10.2012 um 18:40

_________________
Hasta La Victoria Siempre
jfheins
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 918
Erhaltene Danke: 158

Win 10
VS 2013, VS2015
BeitragVerfasst: Do 11.10.12 19:47 
Wenn du das Programm beendest wird der gesamte RAM den das Programm belegt hatte freigegeben. Dafür sorgt Windows :wink:

Zitat:
Dinge wie MemoryStreams, die ich im laufenden Programm erzeuge, werden auch ordnungsgemäß wieder freigegeben. Objekte erzeuge ich während des Programms eigentlich keine.

Jaa neee, ist klar ^^
Also auch wenn du die nicht freigeben würdest - wenn dein Programm beendet wird, wird der Speicher wieder frei.
Terra23 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 872

Win 8
Delphi 7
BeitragVerfasst: Do 11.10.12 21:01 
Moderiert von user profile iconNarses: Komplett-Zitat des letzten Beitrags entfernt.

Danke für deine Antwort. Ich fürchte, dann wird es doch Zeit für nen neuen Laptop. ;)

Was meinst du mit deiner Bemerkung "Jaa neee, ist klar"? Das check ich grad nicht.

_________________
Hasta La Victoria Siempre
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Do 11.10.12 21:20 
Moin!

Ein TMemoryStream ist auch ein Objekt. :zwinker: :idea: :P

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
Mathematiker
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 2622
Erhaltene Danke: 1447

Win 7, 8.1, 10
Delphi 5, 7, 10.1
BeitragVerfasst: Do 11.10.12 21:34 
user profile iconjfheins hat folgendes geschrieben Zum zitierten Posting springen:
Wenn du das Programm beendest wird der gesamte RAM den das Programm belegt hatte freigegeben. Dafür sorgt Windows :wink:

Ist das wirklich ganz sicher? Warum sucht man dann, z.B. mit FastMM4, nach Speicherlecks?
Irgendwie bin ich jetzt verwirrt. :roll: Ich dachte, man muss stets Alles, was man erzeugt, auch selbst wieder löschen, insbesondere die Streams.

Etwas ratlos mit besten Grüßen
Mathematiker

_________________
Töten im Krieg ist nach meiner Auffassung um nichts besser als gewöhnlicher Mord. Albert Einstein
mandras
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 431
Erhaltene Danke: 107

Win 10
Delphi 6 Prof, Delphi 10.4 Prof
BeitragVerfasst: Do 11.10.12 21:56 
Wenn das Progr. beendet wird gibt Windows den belegten Speicher frei.

Natürlich sollten die Teile des Programms bereits vorher den von ihnen belegten und nicht mehr benötigten Speicher freigeben. Einerseits ist sowas ja guter Ton :) andererseits ist eine Funktion die nicht mehr benötigten Speicher nicht freigibt ein Problem spätestens wenn sie öfter aufgerufen wird.

FastMM hilft dabei, derartige "Unterlassungs-Sünden" zu finden.

Für diesen Beitrag haben gedankt: Mathematiker
Delphi-Laie
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1600
Erhaltene Danke: 232


Delphi 2 - RAD-Studio 10.1 Berlin
BeitragVerfasst: Do 11.10.12 22:28 
user profile iconjfheins hat folgendes geschrieben Zum zitierten Posting springen:
Wenn du das Programm beendest wird der gesamte RAM den das Programm belegt hatte freigegeben. Dafür sorgt Windows :wink:


Das war aber nicht immer so. Im Internet geistert(e) der Hinweis, dem mit "alwaysunloaddll" abzuhelfen. Das soll aber seit Windows 2000 überflüssig sein, da es ab jenem Windows ohnehin immer geschieht. Dennoch ist dieser Hinweis ein nicht zu tötender Dauerbrenner. Ich fand ihn vor Jahren sogar in einem PC-Sonderheft (PC intern oder Windows intern), von dem ich bis dato Seriösität annahm. Den Chefredakteur (ein sogar promovierter Herr) angeschrieben, doch der arrogante Heini schwieg darauf nur. War mithin mein letzter Kauf....


Zuletzt bearbeitet von Delphi-Laie am Fr 12.10.12 09:21, insgesamt 1-mal bearbeitet
Gausi
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 8548
Erhaltene Danke: 477

Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
BeitragVerfasst: Do 11.10.12 22:52 
Speicherlecks versucht man zu vermeiden, damit der nicht mehr benötigte Speicher freigegeben wird. Der wird bei Delphi zwar dann nicht direkt an Windows zurückgegeben (afaik), kann aber "recycled" werden, um darin neue Objekte zu speichern. Bei Speicherlecks bleibt der Speicher "belegt", und das Programm muss von Windows immer mehr Speicher anfordern, bis irgendwann nichts mehr geht.

Beim Beenden des Programms wird der Speicher aber auf jeden Fall freigegeben.

_________________
We are, we were and will not be.

Für diesen Beitrag haben gedankt: Mathematiker
Horst_H
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1654
Erhaltene Danke: 244

WIN10,PuppyLinux
FreePascal,Lazarus
BeitragVerfasst: Do 11.10.12 23:23 
Hallo,

Das was Gausi beschreibt ist Grishnak zu Beginn bei seinem Soduko Generator/Löser mal passiert:
www.entwickler-ecke....rder=asc&start=6
Dort wurden dann soviele Objekte erzeugt und nicht wieder freigegeben, dass die Daten plötzlich auf die Festplatte ausgelagert wurden.
Mit einer möglichen Lösung, die Objekte frühest möglich wieder frei zu geben:
www.entwickler-ecke....der=asc&start=14

Gruß Horst
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Fr 12.10.12 10:34 
Moin!

user profile iconmandras hat folgendes geschrieben Zum zitierten Posting springen:
Wenn das Progr. beendet wird gibt Windows den belegten Speicher frei.
Das ist korrekt, sofern es um Speicher geht, den der Delphi-Speichermanager angefordert hat. :zustimm:

Es ist allerdings trotzdem möglich, selbst Speicher über die Windows-API anzufordern, für die Freigabe dieses Speichers ist man dann immer noch selbst verantwortlich, der wird nicht automatisch freigegeben. Das ist z.B. im Umfeld der Funktionen SHGetFolderLocation() so, hier habe ich mal was dazu geschrieben. :les:

So gesehen ist es also durchaus möglich ein Speicherleck zu schrauben, das den für Windows verfügbaren Speicher auch nach Ende des Delphi-Programmes verringert! :shock: IMHO gilt das auch für alle erdenklichen Sprachen oder Script(sprachen), wenn man direkt an die Windows-API ran geht. :nixweiss:

Fazit: Dass es kein guter Stil ist, Speicherlecks fahrlässig in Kauf zu nehmen, "weil Windows ja hinter mir aufräumt", sollte unbestritten sein. Wenn es aber direkt um API-Speicher geht, ist das sogar tödlich! :mahn:

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.

Für diesen Beitrag haben gedankt: Mathematiker
Delphi-Laie
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1600
Erhaltene Danke: 232


Delphi 2 - RAD-Studio 10.1 Berlin
BeitragVerfasst: Fr 12.10.12 13:52 
user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:
So gesehen ist es also durchaus möglich ein Speicherleck zu schrauben, das den für Windows verfügbaren Speicher auch nach Ende des Delphi-Programmes verringert! :shock: IMHO gilt das auch für alle erdenklichen Sprachen oder Script(sprachen), wenn man direkt an die Windows-API ran geht. :nixweiss:


Das muß ja wohl so sein. Der/die/das Windows-API interessiert herzlich wenig, mit welcher Programmiersprache die Befehle erstellt wurden, die dessen/ihre Befehle letztlich aufrufen. Einzige Ausnahme: Die Programmiersprache selbst müßte eingebaute automatische Funktionen haben (die z.B. mit "eincompiliert" oder "eingelinkt" werden), die "Schlampereien" von selbst ausbügeln. Bezweifele ich aber eher, denn Leute, die das Format haben, mit der/die/das API sach- und fachgerecht umzugehen, dürften weit überwiegend auch die Kenntnis und die Routine aufbringen, damit korrekt zu verwenden.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19312
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Fr 12.10.12 17:21 
user profile iconDelphi-Laie hat folgendes geschrieben Zum zitierten Posting springen:
Einzige Ausnahme: Die Programmiersprache selbst müßte eingebaute automatische Funktionen haben (die z.B. mit "eincompiliert" oder "eingelinkt" werden), die "Schlampereien" von selbst ausbügeln.
Das ist nicht möglich. Rein logisch nicht.
Denn wenn das Programm z.B. abstürzt (im Taskmanager abgeschossen, ...), wird schlicht kein Code des Programms mehr ausgeführt. Dementsprechend ist auch nichts da, das aufräumen kann.

Die Resourcen, die über API-Befehle reserviert werden, kann man aber auch ohnehin nicht automatisiert überwachen, da nicht eindeutig definierbar ist wann aufgeräumt werden soll.
Delphi-Laie
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1600
Erhaltene Danke: 232


Delphi 2 - RAD-Studio 10.1 Berlin
BeitragVerfasst: Fr 12.10.12 17:25 
Richtig. Rein logisch bezog ich mich mit diesem Gedankenexperiment auch auf den Fall, daß ein Programm ordnungsgemäß beendet wird. Für den Fall gibt es schließlich auch im Programm einiges (mal mehr, mal weniger) an Code abzuarbeiten.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19312
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Sa 13.10.12 08:48 
Das nennt sich dann Garbage Collector, den es z.B. in Java und C# gibt. In Delphi gibt es den zwar nicht, aber wenn man Interfaces benutzt, werden die Objekte dahinter auch automatisch freigegeben.

Das hilft aber alles nicht bei direkt durch die API reservierten Ressourcen.

Für diesen Beitrag haben gedankt: Delphi-Laie
Oliver Maas
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 55



BeitragVerfasst: Mo 29.10.12 18:37 
Hm. Irgendwie erging es mir bei diesem Thread ähnlich wie Mathematiker.
Ich dachte eigentlich auch, dass der Punkt hinter .Free wäre, den reservierten Speicher freizugeben (Delphi hat ja keine GC wie Java).
Also hab ich immer versucht, die noch vorhandenen Objekte zu "befreien" (Free) bei Programmende.

Nun hatte ich einen speziellen Fall, dass bei einem größeren Programm (Delphi) folgende Situation auftrat:
mein Programm sollte enden, ich hatte alles "befreit", was mir bewusst war.
Dennoch hing der Prozess im Speicher, und ich kriegte dieses Ding einfach nicht beendet.
Schliesslich fiel mir nix besseres ein, als Halt (am Ende des OnClose Events) aufzurufen, wohl im Bewusstsein, dass man das eigentlich nicht machen sollte.
Das funktionierte auch, und - obwohl die Lösung "schlecht" war - gab es damit keine (mir zu Ohren gekommenen) Probleme.

Erwähnenswert ist noch, dass ich eine ganze Zeitlang später in einem Java-Programm ein ähnliches Problem hatte.
Ich vermute, dass es mit irgendeinem Stream zusammenhing, den ich nicht ausfindig machen konnte. Natürlich versuche ich,
alle Streams zu schliessen, aber da war mir irgendeiner "durch die Lappen gegangen" vermutlich.

Olli
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19312
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mo 29.10.12 23:39 
Wenn der Prozess hängt, kannst du .dbg Debuginformationen erzeugen und im Process Explorer schauen in welchem Thread an welcher Stelle da etwas hängt.

Meistens sind das nicht sauber beendete Threads (z.B. auch mit Indy), durch die ein Deadlock entsteht.