Entwickler-Ecke

Sonstiges (Delphi) - Ram Bedarf steigt ständig


Calyptus - So 19.12.04 19:34
Titel: Ram Bedarf steigt ständig
Hallo zusammen...

Mein Problem: Bei meinem Programm steigt der Speicherbedarf die ganze zeit, bis alles voll ist und ein Fehler kommt. Kann mir jmd sagen woran das liegt?

Hier der Code:


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:
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:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
unit Snow2_p;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Timer1: TTimer;
    procedure Button1Click(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
    procedure SnowFirst;
    procedure GetScreenShot (var ABitmap : TBitmap);
  end;

type
  TSnow = record
    x: Integer;
    y: Integer;
    e: Byte;
    s: Boolean;
    xold: Integer;
    yold: Integer;
  end;

const
  SnowMax = 999;
  SnowW = 1280;
  SnowH = 1024;

var
  Form1: TForm1;
  Snow: array[0..SnowMax] of TSnow;
  Pix: Array[0..SnowW, 0..SnowH] of Integer;
  ca:Tcanvas;
  Desk: TBitmap;
  mx, my: Integer;

implementation

{$R *.dfm}


procedure TForm1.SnowFirst;
var
  i: Integer;
begin
  for i := 0 to SnowMax do with Snow[i] do
  begin
    x := Random(SnowW);
    y := Random(SnowH);
    e := Random(4) + 1;
    xold := -1;
    yold := -1;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var a, b: Integer;
begin
  Color := clBlack;
  SnowFirst;
  Desk := TBitmap.Create;
  Form1.Visible := false;
  sleep(100);
  GetScreenShot(Desk);

  a := 0; b := 0;

  while a < SnowW do
   begin
      while b < SnowH do
       begin
        Pix[a,b] := Desk.Canvas.Pixels[a,b];
        b := b + 1;
       end;
       b := 0;
       a := a + 1;
   end;

  Mx := mouse.CursorPos.X;
  My := Mouse.CursorPos.Y;
  Timer1.Enabled := True;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
var
  i: Integer;
begin
  ca:=TCanvas.Create;
  ca.Handle:=GetDC(0);
  for i := 0 to SnowMax do with Snow[i] do
  begin
    Ca.Pixels[xold, yold] := Pix[xold, yold];

    case e of
    1begin
         if s then Inc(x, 1else Dec(x, 1);
         s := not s;
         y := y + 4;
         Ca.Pixels[x, y] := $00FFFFEE;
       end;
    2begin
         if s then Inc(x, 1else Dec(x, 1);
         s := not s;
         y := y + 3;
         Ca.Pixels[x, y] := $00DDDDDD;
       end;
    3begin
         x := x;
         y := y + 2;
         Ca.Pixels[x, y] := $00BBBBBB;
       end;
    4begin
         x := x;
         y := y + 1;
         Ca.Pixels[x, y] := $00999999;
       end;
    end;

    xold := x;
    yold := y;

    if x > SnowW then x := 0;
    if y > SnowH then y := 0;
  end;
  if ( mouse.CursorPos.X <> mx) or (  Mouse.CursorPos.Y <> my ) then
   close;
  ca.Free;

end;

procedure TForm1.GetScreenShot (var ABitmap : TBitmap);
var 
  DC : THandle; 
begin
  if Assigned(ABitmap) then                  // Prüfen ob gültiges Bitmap übergeben wurde 
  begin 
    DC := GetDC(0);                          // Desktop DC holen 
    try 
      ABitmap.Width := Screen.Width;           // Bitmapgrösse den... 
      ABitmap.Height := Screen.Height;         // Bildschirm anpassen 
      BitBlt(ABitmap.Canvas.Handle,            // Dekstop 
             0,0,Screen.Width,Screen.Height,   // in 
             DC,                               // das 
             0,0,                              // Bitmap 
             SrcCopy                           // kopieren 
        ); 
    finally 
      ReleaseDC(0, DC);                        // DC wieder freigeben 
    end
  end
end;

end.


Basti - So 19.12.04 19:40

Ich glaube es zu wissen:
Du erstellst ständig neue Bitmaps mit Desk.Create ohne die alten wieder freizugeben.
Dadurch wird ständig ein neuer Speicherbereich dafür belegt,
auch wenn der alte nicht mehr genutzt wird.
Versuchs mal mit Free an den entsprechenden Stellen.


Calyptus - So 19.12.04 19:47

Aber Desk wird nur einmal erzeugt. dann wenn auf button1 geklickt wird. danach ja nicht mehr...

//edit: Es muss irgendwo im Timer1 liegen, denn wenn dieser deaktiviert wird bleibt der bedarf konstant


Benutzername - So 19.12.04 20:09

Mal was anderes dazu:
Im OnTimer createst du immer an Anfang ein Canvas namens ca, und am Ende gibst du es wieder frei.
Erstelle es doch einmal im FormCreate und Free-e es im FormClose/Destroy etc.
Dazu musst du es natürlich global definieren ;-)


Calyptus - So 19.12.04 21:42

Jope danke. das wars :D