Einzelnen Beitrag anzeigen

Benutzerbild von negaH
negaH

Registriert seit: 25. Jun 2003
Ort: Thüringen
2.950 Beiträge
 
#25

Re: FastMM grotten langsam ?!

  Alt 19. Nov 2005, 03:01
Zitat:
1.) Wäre es überhaupt denkbar einen Speichermanager so anzupassen, dass er bei Com und OLE Objekten keinen größeren Speicherbereich anfordert, also nur auf normale Objekte mit seiner Optimierung reagiert.
Um die Größe des Overheads geht es hier garnicht. Es geht noch nicht mal um die Allozierung sondern um die Deallozierungen, diese sind das Problem.

Man könnte mit Sicherheit einen MM programmieren der mehrere GetMem() Funktionen besäße. Je nach gewünschtem Verhalten würden diese GetMem() Versionen unterschiedliche Speuicheranforderungen durchführen. Zb. eben ein GetMem() für die LongStrings die mit hoher Wahrscheinlichkeit ReallocMem() aufrufen. Und ein anderes GetMem() für Speicherbereiche die immer fixierte Länge besäßen.

Zitat:
2.) Endet das letztlich in einer Art zeitgesteuerten Garbage-Collection. Dein Speichermanager müßte ja in den Idle-Zeiten genauer Untersuchen welche Speicherlücken er noch freigeben kann.
Nee. Alle MMs die ich kenne entscheiden sofort wie sie einen freizugebenden Speicherbereich wieder defragmentiert einzuordnen haben. Sie erkennen also schon bei der Deallokation ob die Speicherbereiche nach und vor dem aktuellen ebenfalls schon freigegeben wurden. Ist dies der Fall werden diese Fragmente sofort zu einem größeren Block zusammengeführt.

Die Idle Methode bezog sich darauf die Threadeigenen MMs innerhalb vom recyclerMM wieder freizugeben. Dabei wird periodisch überprüft ob zu einem Threadeigenem MM der Thread noch gültig ist. Nur gibt es eben auf API Ebene keinen Weg zu erkennen ob ein Thread Handle oder ThreadID noch gültig ist. Dies ist im Grunde exakt das gleiche Problem mit Objektreferenzen. Also Zeiger auf Objekte bei denen aber das Objekt schon längst wieder freigegeben wurde. Der Objektzeiger zeigt also in einen Speicherbereich in dem schon längst nicht mehr das originale Objekt gespeichert ist sondern entweder garkeines oder noch viel schlimmer ein neues der gleichen Klasse, aber eben NICHT mehr das originale ! Da Windows ebenfalls die Handles in der internen Handletabelle zum Prozess wiederverwendetet und unter Win95 zb. die ThreadID direkt korrespondiert zum Speicherbereich des Threadhandles (ThreadID ist quasi ein umgerechneter Wert des Speicherbereiches auf den das Handle zeigt), entsteht somit exakt das gleiche Problem wie bei den Objekten. Man kann definitiv nicht erkennen ob ein Thread Handle/ID noch der original gemeinte Thread ist.

Zitat:
3.) Ist das nicht eher die Aufgabe eines Programm unabhängigen Dienstes?
Hm, weis ich nicht. Ob man das als Dienst, DLL oder ins Kernel einbaut ist erstmal egal, Code bleibt Code. Wohin man das einbaut hat nur Relevanz bei der finalen Entscheidung in welcher Form man das Produkt vermarkten möchte. Der Ort wo der Code steht entscheidet also erstmal nicht was der Code ansich für Aufgaben erledigen soll.
Man kann zb. einen TCP/IP Server als DLL, Dienst oder eigene Anwendung programmieren, dadurch ändert sich aber nichts am Verhalten des Servers ansich.

Zitat:
2.) Endet das letztlich in einer Art zeitgesteuerten Garbage-Collection. Dein Speichermanager müßte ja in den Idle-Zeiten genauer Untersuchen welche Speicherlücken er noch freigeben kann.
Ich vermute mal das du mit dieser Frage eher auf den "strategisch intelligenten" MM anspieltest. Wie ich oben sagte wäre das das einzigste was mich überhaupt dazu bewegen könnte nochmals einen MM zu coden (neben einem finanziellen Profit wohlgemerkt )

Konzeptionell würde ich ein solches System aber anders angehen. Zb. einen MM der einen "Lern-modus" enthält. Wie oben angedeutet gäbe es verschiedene GetMem() Funktionen. Eine für definitiv sich reallokierende Funktionen und einen für fixed Size Allokationen.

Man bindet einen solchen MM ganz normal in seine Anwendung ein, per Compilerswisches im "Lern"-Modus. Der MM protokolliert nun jede Speicherallokation und auch die Reallokationen schon bestehender Speicherbereiche. Ausgehend davon ermittelt er also mit welcher GetMem() Funktion,sprich welchen Typus von Speicher die Anwendung zu jedem zeitpunkt benötigt. Daraus ermittelt er zb. das Funktion XYZ immer nur Speicher alloziert mit fester Größe a 32 Bytes. Diese Information führt dazu das im Patch-Modus der MM eine spezielle GetMem() Funktion an die originale Stelle des Funktionsaufrufes hinein "patcht". Die Funktion XYZ ruft ab jetzt immer eine GetMem() Funktion auf die nur Blöcke von 32 Bytes in einem speziellen Speicherbereich alloziert.

Oder Funktion ABC führt eine LongString Berechnung durch. Dabei wird er String additiv vergrößert, von zb. 4 Zeichen auf durchscnittlich 1024 Zeichen +-128 Zeichen. Diese statistischen Infos werden im MM im Lernmodus ermittelt und führen nun im gepatchten Modus dazu das der erste Aufruf von GetMem() in Funktion ABC sofort einen String mit Länge 1024 alloziert.

So bei diesem MM gäbe es noch einen Lernmodus und eine finale gepatchte Anwendung. Schafft man es dies statistischen Informionen aber kompakt und permanent aktuell zu halten so könnte man auch auf diese 2 Phase verzichten und der MM würde quasi permanent lernen und entscheiden.

Gruß Hagen
  Mit Zitat antworten Zitat