Entwickler-Ecke

Off Topic - Speicherverbrauch !!!


Jagg - Mi 15.10.03 21:14
Titel: Speicherverbrauch !!!
Ich habe ein Programm geschrieben,es ist schon fast fertig,aber das Problem ist nur,es verbraucht VIEL Speicher(Ressourcen),woran kan es denn gurndgemäß liegen,benutze ich zuviele schleifen oder so ?

Jagg


CenBells - Mi 15.10.03 21:21

Hallo,

das ist prinzipiell so wie mit der Glaskugel ("wo kommt der ganze Nebel her?") - Nee im ernst.

Prinzipiell kann es daran liegen das du viele Objekte initialisierst sie aber nicht mehr freigibst. Aber es gibt möglichkeiten wie sand am mehr (und der ist abzählbar unendlich .. *G*)

Gruß
Ken


Jagg - Mi 15.10.03 21:28

meinst du mit objekten ...komponenten oder variablen ???


CenBells - Mi 15.10.03 21:34

objekt = TObjekt. Vorfahr aller Klassen in der Pascal Klassenhierachie.

Variablen können genauso zeiger auf TObjekt-Nachkommen sein, wie zeiger auf speicher, der dann als String, Integer etc gelesen wird.

Also prinzipiell musst du speicher von instantiierten objekten wieder frei geben.

Gruß
Ken


Jagg - Mi 15.10.03 21:39

ok noch eine frage wie mache ich das
z.b ich habe die variable zahl und wenn die in einem bestimmten vorgang nicht gebrauchen kann,wie gebe ich die wieder frei ?
meint ihr das mit freigeben ?


CenBells - Mi 15.10.03 21:46

du hast es nicht so richtig verstanden, oder?
Variablen (Integer...) alloziieren nur im Gültigkeitsbereich einer prozedur speicher. Der wird am ende der Prozedur wieder automatisch frei gegeben.

Gruß
Ken


Jagg - Mi 15.10.03 21:50

also ich glaube ich bin zu blöd dafür
ich galube ich das brauche das mal erklärt an einem beispiel ...


Delete - Mi 15.10.03 22:40


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
var
  sl: TStringlist;
begin
  sl := TStringList.Create;  // Instanz der Klasse im Speicher erzeugen - > Objekt
  if Assigned(sl) then
  begin
    try
      sl. ...;
    finally
      FreeAndNil(sl);  //  Objekt und Speicher wieder freigeben
    end;
  end;


Popov - Mi 15.10.03 22:51

Luckie hat schon ein Beispiel gegeben, aber noch mal ganz leicht verständlich. Fast alle (bzw. viele) "Variablen", z.B.:

var
Bmp: TBitmap;
Sl: TStringList;

die mit einem T anfangen, sind (oder könnten sein) Objekte. Das ist aber keine Regel und es gibt auch Typen, die mit T anfangen und keine Objekte sind. Aber bis du so weit bist es selbst zu erkennen, solltest du alle Typen die mit T anfangen etwas genauer beachten. Woran du aber Objekte ganz genau erkennst, daß ist, daß sie Create't werden müssen. Was aber create't wurde, das muß auch mit Free wieder selbst freigegeben werden.

So, die anderen werden mich für diese Aussage steinigen, aber wenn's dir hilft, dann ist es ok.


Delete - Mi 15.10.03 23:05

Jehova, Jehova, ....

Alle selbst erzeugten Instanzen einer Klasse, muss man auch wieder freigeben, sonst müllt man sich den eigenen Speicher der Anwendung voll.


Andi1982 - Do 16.10.03 07:12

Hallo,
@Jagg woher weißt du dass dein Programm viel Hauptspeicher braucht? Kann man das irgendwo sehen? Ich wüsste das von meinen Programmen auch gerne mal...


Delete - Do 16.10.03 07:36

In der Prozessliste vom Taskmanager wird es angezeigt, zu mindest im Taskmanager von 2000 und XP Professionel, wie es bei dem von der Home Edition aussihet weiß ich nicht. Es gibt aber noch diverse Tools, wie zum Beipiel MemProof für Delphi.


Andi1982 - Do 16.10.03 07:38

Oh gut zu wissen, werde mich mal nach dem Tool umschauen! Danke!


Jagg - Do 16.10.03 08:16

also ich habe nichts mit objekten und so weiter !
ich habe aber viele variablen die ich global initialisiert habe,kann es vllt daran liegen ?
muss ich die variablen lokal machen ???

Jagg !


Delete - Do 16.10.03 08:19

Globale variablen belegen wärend des gesamten Programmablaufs Speicher, lokale nur in der Prozedur / Funktion. Und wenn du so vile globale Variablen hast, dann hast du das OOP Prinzip nicht verstanden.


Jagg - Do 16.10.03 09:01

ja stimmt da hat du whrscheinlich recht
ich mache jetzt mal die globale in lokalen mal sehen ob das jetzt geht


patrick - Do 16.10.03 09:31

kann es sein das du einen haufen zwischenvariablen hast und diese nicht leerst?
du kannst je die globalen variablen jedes mal wenn sie nach einer schleife nicht mehr gebraucht wird leeren.

bei string: variable1:='';
bei integer: variable2:=0;


Delete - Do 16.10.03 09:42

Und was bringt das? Bei Strings (dynamischen arrays) könnte ich es noch verstehen, aber bei Integers? Ein Integer belegt vier Byte, egal ob da 0 oder mein Gehalt vom letzten Jahr drin steht.


joerg68 - Do 16.10.03 10:00
Titel: Speicherverbrauch
Verwendest Du in Deinem Programm QUerys oder Tables ? Die können auch ganz schön viel Speicher fressen.
Du könntest auch mal beschreiben was Du in deinem Programm macht.
Etwas Quellcode wäre vielleicht auch nicht schlecht.
Nur mit der Angabe, daß Du Komponeten und globale / lokale Variablen hast, kann man nicht viel anfangen. Die hat wohl jedes Programm.

Gruss
Jörg


Jagg - Do 16.10.03 10:48

ich habe hier ein code

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:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
Procedure Alle_Links;
begin
  try
    StartPos := 0;
    laufmail := 0;
    while Startpos <> -1 do
    begin
      EMailSuchen_links;
      EMailSuchen_rechts;
      if TextMail<>'' then
        Form1.Memo_Mail.Lines.Append(Textmailklein);
      Textmail := '';
      Wertesetzen;
      end;
    StartPos_web := 0;
    while Startpos_web <> -1 do
    begin
      Web_suche;
      Wertesetzen;
    end;
    StartPos_web_http := 0;
    while Startpos_web_http <> -1 do
    begin
      Web_suche_http;
      Wertesetzen;
    end;
    StartPos_web_www := 0;
    while Startpos_web_www <> -1 do
    begin
      Web_suche_www;
      Wertesetzen;
    end;
    Mail_Doppelt;
    i_adressfilter := 0;
    i_adressfilter1 := 0;
    Adressfilter;
    Form1.Memo_end.Text := Form1.Memo_Mail.Text;
       if Form1.Memo_web.text<>'' then
    begin
      Memo_web_anzahl := Form1.Memo_web.Lines.Count;
      Memo_web_lauf := 0;
      Memo_web_string := Form1.Memo_web.Lines[Memo_web_lauf];
      if (pos('http://',Memo_web_string)>0) or (pos('www',Memo_web_string)>0) then
        Form1.ed_Url.Text := Memo_web_string
      else
        Form1.ed_Url.Text := Form1.ed_website.text+Memo_web_string;
        if Memo_web_string<>'' then
      begin
        Form1.Memo_web.Lines.Delete(Memo_web_lauf);
        dec(AnzahlzuURL);
        Form1.Anzeige.Panels[2].Text := ' URL zu bearbeiten : '+IntToStr(AnzahlzuURL);
        if Form1.ed_Url.text<>'' then
        begin
          Form1.NMHTTP1.Get(Form1.ed_Url.text);
          Form1.REdit_Q.Lines.Text := Form1.NMHTTP1.Body;
        end;
        if Form1.Memo_Web.text = '' then
          Form1.ed_Url.Clear;
        if Stop = 1 then
          Exit;
        Alle_Links;
      end;
    end;
    except
      Alle_links;
    end;
end;

.... der sucht hier immer wieder nach "Links"...,das ist hier vllt der fehler...ich muss hier glaube ich einen Timer setzen und immer nach 2 oder 3 sekunden die procedure aufrufen oder was sagt ihr dazu ???

Jagg


Jagg - Di 28.10.03 19:00

weiss keiner rat ??? für mich ???