Autor |
Beitrag |
r4id3n
Beiträge: 115
Win XP Home, Win XP Pro
D6 Prof, D7 Ent, K3 Ent
|
Verfasst: 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
Beiträge: 552
(D3/D7/D8) Prof.
|
Verfasst: 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
Beiträge: 115
Win XP Home, Win XP Pro
D6 Prof, D7 Ent, K3 Ent
|
Verfasst: 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
Beiträge: 19
Gentoo Linux, Win XP Pro
D6 Prof, K3 Open, Freepascal
|
Verfasst: 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
Beiträge: 115
Win XP Home, Win XP Pro
D6 Prof, D7 Ent, K3 Ent
|
Verfasst: Do 24.02.05 11:19
Nachfrag ,
hast du ein kurzes Codebeispiel?
THX
|
|
dmx
Beiträge: 19
Gentoo Linux, Win XP Pro
D6 Prof, K3 Open, Freepascal
|
Verfasst: 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...
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.
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 <> nil) then begin pptrint(CGetMem)^ := size; inc(CGetMem,sizeof(ptrint)); end; end;
Function CFreeMem (P : pointer) : ptrint;
begin if (p <> nil) then 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 <> nil) then 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 <> nil) then 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 <> nil) then 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:
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
Beiträge: 115
Win XP Home, Win XP Pro
D6 Prof, D7 Ent, K3 Ent
|
Verfasst: Fr 25.02.05 11:12
THX, ich werds übers WE mal ausprobieren!
|
|
maximus
Beiträge: 896
Win XP, Suse 8.1
Delphi 4/7/8 alles prof
|
Verfasst: 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
Beiträge: 115
Win XP Home, Win XP Pro
D6 Prof, D7 Ent, K3 Ent
|
Verfasst: Fr 25.02.05 11:32
Das sind leider verschiedene klassen ... Ist zwar alles eine Basisklasse, aber relativ viele davon abgeleitete klassen.
|
|
|