Autor Beitrag
r4id3n
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 115

Win XP Home, Win XP Pro
D6 Prof, D7 Ent, K3 Ent
BeitragVerfasst: Fr 14.01.05 11:43 
Hallo zusammen, ich suche einen guten alternativen Memory Manager ....

Ich arbeite an einem Serverdienst, der sehr viel Speicher braucht, genauer, der oft viele Objekte anlegt und wieder frei gibt ... Aufgrund der Memoryallokation von Delphi, ist aber leider der Speicher relativ schnell voll und stark fragmentiert ....


Kennt jemand ein paar gute MMs, eventuell auch für Kylix??

THX
Spaceguide
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 552


(D3/D7/D8) Prof.
BeitragVerfasst: Fr 14.01.05 20:34 
Irgendwo hat jemand mal einen Vergleich des Borland MM mit den tollen "verbesserten" MMs gemacht und herausgefunden, dass die alle langsamer sind. Woran siehst du die Fragmentierung des Speichers? Probier doch mal den RecyclerMM aus, der behauptet weniger zu fragmentieren.
r4id3n Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 115

Win XP Home, Win XP Pro
D6 Prof, D7 Ent, K3 Ent
BeitragVerfasst: Fr 14.01.05 20:52 
Das der verwendete Speicher immer größer wird, obwohl alle Objekte gefreet werden ....
Den Recycler kenne ich schon, allerdings, leider kein Kylix :-(

Dachte es kennt villeicht jemand noch ein paar andere!
dmx
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 19

Gentoo Linux, Win XP Pro
D6 Prof, K3 Open, Freepascal
BeitragVerfasst: Do 24.02.05 01:18 
hallo,

gerade bei "kritischen" anwendungen wie der programmierung von server-programmen hab ich unter freepascal wie unter kylix - unter linux zumindest - die erfahrung gemacht, dass es sehr sinnvoll ist, die mm-funktionen der libc zu verwenden!

wenn du genaueres wissen willst, frag nach.

gruß, dmx.
r4id3n Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 115

Win XP Home, Win XP Pro
D6 Prof, D7 Ent, K3 Ent
BeitragVerfasst: Do 24.02.05 11:19 
Nachfrag ;-),

hast du ein kurzes Codebeispiel?

THX
dmx
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 19

Gentoo Linux, Win XP Pro
D6 Prof, K3 Open, Freepascal
BeitragVerfasst: Fr 25.02.05 00:04 
hallo,

klar. vorweg sei noch gesagt, dass der heap-manager bei delphi/kylix/freepascal seinen dienst zum teil und in den versionen die ich kenne, zwar zügig, aber nicht sehr ordentlich verrichtet. einer der compiler-bauer von freepascal sagte mir mal das hängt damit zusammen, dass der heap-manager einmal allozierten speicher auc hdann nicht wieder freigibt, wenn objekte bereits wieder "zerstört" worden sind. das führt dann zu memory-leaks.

erstmal müssen die nötigen funktionen der libc dem pascal-compiler bekannt gemacht werden...

ausblenden Delphi-Quelltext
1:
2:
3:
4:
Function Malloc (Size : ptrint) : Pointer; {$ifdef win32}stdcall{$else}cdecl{$endif}external LibName name 'malloc';
Procedure Free (P : pointer); {$ifdef win32}stdcall{$else}cdecl{$endif}external LibName name 'free';
function ReAlloc (P : Pointer; Size : ptrint) : pointer; {$ifdef win32}stdcall{$else}cdecl{$endif}external LibName name 'realloc';
Function CAlloc (unitSize,UnitCount : ptrint) : pointer; {$ifdef win32}stdcall{$else}cdecl{$endif}external LibName name 'calloc';


dann kann man die neuen funktionen definieren, die denen des memory-managers (nur ein "c" davor) entsprechen (der code stammt direkt aus der freepascal rtl). ptrint ist ein integer, der die länge eines pointer besitzt.

ausblenden volle Höhe 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:
Function CGetMem  (Size : ptrint) : Pointer;

begin
  CGetMem:=Malloc(Size+sizeof(ptrint));
  if (CGetMem <> nilthen
    begin
      pptrint(CGetMem)^ := size;
      inc(CGetMem,sizeof(ptrint));
    end;
end;

Function CFreeMem (P : pointer) : ptrint;

begin
  if (p <> nilthen
    dec(p,sizeof(ptrint));
  Free(P);
  CFreeMem:=0;
end;

Function CFreeMemSize(p:pointer;Size:ptrint):ptrint;

begin
  if size<=0 then
    begin
      if size<0 then
        runerror(204);
      exit;
    end;
  if (p <> nilthen
    begin
      if (size <> pptrint(p-sizeof(ptrint))^) then
        runerror(204);
    end;
  CFreeMemSize:=CFreeMem(P);
end;

Function CAllocMem(Size : ptrint) : Pointer;

begin
  CAllocMem:=calloc(Size+sizeof(ptrint),1);
  if (CAllocMem <> nilthen
    begin
      pptrint(CAllocMem)^ := size;
      inc(CAllocMem,sizeof(ptrint));
    end;
end;

Function CReAllocMem (var p:pointer;Size:ptrint):Pointer;

begin
  if size=0 then
    begin
      if p<>nil then
        begin
          dec(p,sizeof(ptrint));
          free(p);
          p:=nil;
        end;
    end
  else
    begin
      inc(size,sizeof(ptrint));
      if p=nil then
        p:=malloc(Size)
      else
        begin
          dec(p,sizeof(ptrint));
          p:=realloc(p,size);
        end;
      if (p <> nilthen
        begin
          pptrint(p)^ := size-sizeof(ptrint);
          inc(p,sizeof(ptrint));
        end;
    end;
  CReAllocMem:=p;
end;

Function CMemSize (p:pointer): ptrint;

begin
  CMemSize:=pptrint(p-sizeof(ptrint))^;
end;

Procedure CGetHeapStatus(var status:THeapStatus);

begin
  fillchar(status,sizeof(status),0);
end;


unter windows müssten aber auch GlobalAllocPtr und GlobalFreePtr (Unit Windows) weiterhelfen. denkbar einfach in etwa so:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
function MGetMem(Size : Integer) : Pointer;
begin
  if Size=0 then Error;
  Result:=GlobalAllocPtr(GMEM_FIXED, Size);
  if Result=nil then Error
end;

function MFreeMem(P : Pointer) : Integer;
begin
  Result:=GlobalFreePtr(P);
  if Result<>0 then Error
end;

function MReallocMem(P : Pointer; Size : Integer) : Pointer;
begin
  Result:=GlobalReallocPtr(P, Size, GMEM_MOVEABLE);
  if Result=nil then Error
end;


fragen immer an mich.

gruß, dmx
r4id3n Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 115

Win XP Home, Win XP Pro
D6 Prof, D7 Ent, K3 Ent
BeitragVerfasst: Fr 25.02.05 11:12 
THX, ich werds übers WE mal ausprobieren!
maximus
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 896

Win XP, Suse 8.1
Delphi 4/7/8 alles prof
BeitragVerfasst: Fr 25.02.05 11:23 
Jenachdem was das für objekte sind, kann sich auch prima selbst einen node-manager schreiben. Hat man es mit vielen objekten der selber klasse zu tun, so kann man die instanzierung um den faktor 3 bescchleunigen und hat genau kontrolle darübe wie die objekte im speicher liegen. Man reserviert halt immer grössere chunks und weisst den objekte den platz selber zu.

_________________
mfg.
mâximôv
r4id3n Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 115

Win XP Home, Win XP Pro
D6 Prof, D7 Ent, K3 Ent
BeitragVerfasst: Fr 25.02.05 11:32 
Das sind leider verschiedene klassen ... Ist zwar alles eine Basisklasse, aber relativ viele davon abgeleitete klassen.