Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - speicher läuft über


klausiemausie - Di 10.02.09 16:59
Titel: speicher läuft über
ich habe folgendes problem: ich habe ein spiel programmiert, in dem man europa erobern muss, jedes land europas liegt in einer image, mit transparentem hintergrund. wenn nun einheiten verschoben werden, und ein land erobert wird, wird ein bild in das image reingeladen, das funktioniert auch alles, nur läuft mein ram voll, je länder ich das spiel spiele, desto mehr ram brauch das, woran liegt das? und wie kann ich den ram freigeben?


Gausi - Di 10.02.09 17:01

Du erzeugst anscheinend irgendwo Bitmaps oder andere speicherintensive Objekte, gibst sie aber nicht mehr frei, wenn du sie nicht mehr benötigst.

Schau mal in deinen Code. Immer wenn irgendwo create steht, muss irgendwo auch wieder ein free auftreten.


klausiemausie - Di 10.02.09 17:36

naja wie gesagt, in meiner form 1 sind mehrere images, die immer mit einem neuen bild geladen werden, aber anscheind, schreibt delphi einfach nur das neue bild in den speicher, aber nimmt dafür einen neuen speicher, wie schreib ich denn dann, dass da der alte speicher freigegeben werden soll?


jaenicke - Di 10.02.09 17:40

BitmapX.Free, wenn es eine TBitmap ist. Generell musst du im Normalfall überall wo du etwas mit Create erzeugst auch genau ein Free dazu haben.
Zudem gibt es noch FreeImage. Das entfernt nur das Bild aus dem Speicher.


klausiemausie - Di 10.02.09 17:42

gut schreib ich das hin bevor, er das neue bild lädt, oder danach?


jaenicke - Di 10.02.09 17:48

Danach wäre das neue Bild ja weg und nicht das alte. Grundsätzlich ist die Frage vor allem, ob du jedesmal die Bitmap ganz neu erstellst?

Mit FastMM kann man z.B. nach Speicherlecks suchen, wenn man die entsprechende Option anschaltet.


klausiemausie - Di 10.02.09 17:50

nein wird nicht neu erstellt, nur ein neues bild reingeladen als beispiel so

Delphi-Quelltext
1:
form1.Frankreich.Picture.LoadFromFile(ExtractFilePath(ParamStr(0)) + ('\Länder\Frankreich_1.png'));                    


Moderiert von user profile iconNarses: Delphi-Tags hinzugefügt


JayEff - Di 10.02.09 17:52

user profile iconklausiemausie hat folgendes geschrieben Zum zitierten Posting springen:
gut schreib ich das hin bevor, er das neue bild lädt, oder danach?
:nixweiss:
Poste doch mal ein paar Abschnitte aus deinem Code :)
An sonsten: Normal prüft man, ob Speicher schon reserviert wurde (z.B. if Assigned(myBitmap) then ...) und falls ja, gibt man ihn frei, bevor man neuen reserviert (Es bietet sich FreeAndNil(myBitmap); an.)

Ok, deinem Code zufolge liegt das Problem nicht da, das Image sollte kein Speicherleck verursachen.
Rufst du irgendwo mal etwas wie aVar := TmyObject.Create; auf? Poste entsprechende Stellen mal.


klausiemausie - Di 10.02.09 18:40

also ich hab mal nach geguckt, an welcher stelle, sich die speichernutzung erhöht, das passiert, wenn ich einheiten verschiebe, wenn ich einheiten verschieben will klick ich auf einen button, es öffnet sich ein fenster, mit showmodal, und da kann man in einer combobox das land auswählen, und in ein editfeld schreiben, wieviel einheiten man verschieben will. hier mal der code dazu, wenn mir mal jemand erzählen würde, wie man die delphi tags hinzufügt, das wär herrlich.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
if anzahl<0 then form48.showmodal; //zeigt ein fenster "keine negatigen einheiten"
if (anzahl<=form1.Region[7]) and (anzahl>=0then  begin //anzahl ist die menge der zu verschiebenden einheiten, region[7] die stationierten einheiten in land nr.7
if form1.zielland=74 then begin //zielland gibt an von welchem land in welches verschoben wird (hier 7-4), wird bei auswahl in der combobox geändert
                if form1.zugehoerigkeit[7]<>form1.zugehoerigkeit[4]then begin //wenn die länder nicht ein und dem selben spieler gehören
                a:=form1.region[4];
                b:=anzahl;
                a:=a-b;
                if a>=0 then form46.ShowModal; //zeigt an, dass die eroberung fehlgeschlagen ist
                a:=0;
                b:=0;
                form1.region[4]:=(round(form1.region[4]*1.2)-anzahl); //einheiten des angegriffenen landes werden erneuert, 1.2 ist ein verteidigungsbonus
                form1.Region[7]:=form1.region[7]-anzahl; end //die einheiten des angreifenden landes werden verringert um die anzahl der eingegebenen einheiten
                else if form1.zugehoerigkeit[7]=form1.zugehoerigkeit[4]then begin //wenn beide länder einem besitzer gehören, ledigliech einheitenverschiebung
                form1.verschieben[4]:=form1.verschieben[4]+anzahl;
                form1.Region[7]:=form1.region[7]-anzahl; end
                end;

                if form1.region[4]<0 then begin form1.Region[4]:=0-form1.region[4]; //wenn die einheiten des angegriffenen landes unter 0 kommen (nur bei angriff möglich)
                                                form1.zugehoerigkeit[4]:=form1.zugehoerigkeit[7]; //zugehörigkeit wird mit der des angreifers überschrieben
                                                form5.klick:=1//ist eine laufvariable, die verhindert, dass in einer runde aus einem land mehrmals verschoben wird
                                                form45.ShowModal; //zeigt, dass die eroberung erfolgreich war
                                                end;
                if form1.zugehoerigkeit[4]=1 then begin form1.Frankreich.Picture.LoadFromFile(ExtractFilePath(ParamStr(0)) + ('\Länder\Frankreich_1.png')); //lädt das bild für die zugehörigkeit zu spieler1
                end;
                if form1.zugehoerigkeit[4]=2 then begin form1.Frankreich.Picture.LoadFromFile(ExtractFilePath(ParamStr(0)) + ('\Länder\Frankreich_2.png')); //und hier für spieler 2
                end;


Moderiert von user profile iconNarses: Delphi-Tags hinzugefügt


GTA-Place - Di 10.02.09 19:20

Mal was anderes: Wieso brauchst du so viele Forms? Ein MessageDlg oder ShowMessage würde doch reichen in den meisten Fällen.


klausiemausie - Di 10.02.09 19:26

für jedes land, aus dem ich einheiten verschieben kann, hab ich eine extra vverschiebungsform, weil ichs nich besser wusste als delphianfänger, wie man das mit einer form lösen könnte, dann kommen noch einige forms hinzu, für interne fehlermeldungen, wie zum beispiel negative einheiten eingegeben, kein land ausgewählt, etc. dann noch ein möchten sie wirklich beenden , ein introvideo, eine form, wo beide spieler ihren namen eingeben etc. deswegen kommen so viele forms zustande.


klausiemausie - Fr 13.02.09 20:36

ok, problem gelöst, ich hab den grund gefunden, warum mein prog soviel speicher gefressen hat, und zwar hatte ich ja für jedes land ein Bild gehabt, allerdings war das riesig gross, mit 1900 noch was pixeln, und nur oben in der linken ecke war das land, was dann reingeladen wurde, und das brachte den speicher natürlich zum überlaufen.
danke für eure antworten trotzdem