FREAKED'S RETROSPACE - Keeping old technology alive

=============================================================================

\\\\ Startseite | Infoportal | Kontakt ////

=============================================================================

Infoportal * Microsoft Windows 3.x-Dienstprogramm Fix1MB

-----------------------------------------------------------------------------

MEMO Diesen Beitrag auf der neuen Seite lesen

Mai 1995, Ausgabe des Microsoft Systems Journal, Spalte „Fragen und Antworten“
Autoren: Pietrek, Matt
Download: fix1mb.zip

In meiner ersten Kolumne für MSJ (Oktober 1993) schrieb ich etwas, das ich als Wegwerfdienstprogramm mit dem Namen Below 1MB bezeichnete. Diese Spalte, die vom üblichen Frage-Antwort-Format abweicht, beschreibt Fix1MB, ​​ein Update zu Below1MB. Der Zweck von Below1MB bestand darin, Ihnen dabei zu helfen, festzustellen, welche Ihrer eigenen DLLs und Treiber den wertvollen linearen Adressraum unter 1 MB aufsaugen. Windows 3.x und Windows 95 benötigen für jede gestartete Aufgabe eine kleine Speichermenge von weniger als 1 MB. Wenn es den Speicher nicht zuweisen kann, erhalten Sie eine etwas verwirrende Meldung "Nicht genügend Speicher zum Ausführen dieses Programms", unabhängig davon, wie viel RAM Sie installiert haben. Als ich Below1MB schrieb, hätte ich mir kaum vorstellen können, dass es außerhalb von Programmierkreisen bemerkt werden würde. Endbenutzer haben es verwendet,

Leider ist die Speicherknappheit bei MS-DOS so schlimm (insbesondere in Windows for Workgroups 3.11), dass sogar Endbenutzer nach allem greifen, was helfen könnte, selbst wenn sie viele der bereitgestellten Informationen nicht verstehen . Hätte ich gewusst, dass Below1MB ein so breites Publikum haben würde, hätte ich es vielleicht anders geschrieben und dabei besonders darauf geachtet, Details zu reduzieren, die nicht direkt mit dem Hauptproblem zusammenhängen. Wie Sie vielleicht schon erraten haben, habe ich Below1MB endlich umgeschrieben, um die Verwendung zu vereinfachen und (was noch wichtiger ist) tatsächlich zu helfen, das Problem zu beheben. Mein Fix1MB-Programm sollte sowohl für Programmierer wegen der verwendeten Techniken als auch für Endbenutzer interessant sein, die nur nach einer schnellen Lösung suchen.

Das unter einem Megabyte-Problem

-----------------------------------------------------------------------------


Für diejenigen unter Ihnen, deren frühere MSJ-Probleme nicht praktisch sind, gebe ich einen kurzen Überblick über das Problem in Windows, das Fix1MB behebt. Jedes laufende Programm in Windows ist eine separate Aufgabe. Jeder Aufgabe ist eine Systemdatenstruktur zugeordnet, die als Aufgabendatenbank (oder TDB) bekannt ist. Eine Aufgabendatenbank enthält wichtige Informationen über eine Aufgabe, wie z. B. ihr aktuelles Verzeichnis, ihre HINSTANCE und ein MSDOS PSP (Program Segment Prefix). Die Größe jeder Task-Datenbank beträgt 0x200 Bytes (eine wichtige Zahl, die später noch genannt wird). In Windows 3.x muss jeder Task-Datenbank eine Adresse zugewiesen werden, die unter einer linearen Adresse von 1 MB liegt. Warum ist das so? Windows 3.x verwendet immer noch ausgiebig Real-Mode-MSDOS, und viele MS-DOS-Funktionen benötigen Zugriff auf eine PSP. Da die im Realmodus maximal zugängliche Adresse 1 MB beträgt (eigentlich 1 MB + 64 KB - 16),

Wenn Windows gestartet wird, platziert es jeden nicht verwendeten MS-DOS-Speicher unter 1 MB im globalen Heap. Dieser MS-DOS-Speicher bildet den untersten Teil des gesamten globalen Windows-Heapspeichers. Normalerweise befinden sich möglicherweise 300 KB im globalen Heap, das aus diesem niedrigen MS-DOS-Speicher stammt. Mit 300 KB Arbeitsspeicher zum Spielen sollten Sie in der Lage sein, ungefähr 2400 Aufgabendatenbanken zu erstellen, was selbst für die hartgesottensten Multitasker ausreichen sollte.

Das Problem bei diesem Setup hängt damit zusammen, wie Windows globalen Heap-Speicher zuweist. Normalerweise beginnt der globale Heap-Manager beim Zuweisen von Speicher seine Suche am unteren Ende des globalen Heaps und stoppt, wenn er den ersten Block findet, der groß genug ist. (Die Ausnahme ist das Zuweisen von Speicher für verwerfbare Codesegmente, was dazu führt, dass Windows die Suche am oberen Ende des Heaps beginnt. Da der untere Teil des globalen Heaps den übrig gebliebenen niedrigen MS-DOS-Speicher umfasst, enden viele globale Heap-Zuweisungen von Adressen unter 1 MB kommen.Wenn keine besonderen Vorkehrungen getroffen werden, belegt die globale Heap-Zuweisung schnell den gesamten Speicher unter 1 MB, wodurch es unmöglich wird, eine weitere Aufgabendatenbank zu erstellen (und somit eine neue Aufgabe zu starten).

Windows verhindert, dass der Speicher unter 1 MB schnell aufgebraucht wird, indem es die meisten Blöcke verschiebbar macht. Selbst wenn ein Block ursprünglich unter 1 MB zugewiesen wurde, verschiebt der globale Heap-Manager den Block im linearen Speicher nach oben, um Platz für einen anderen Block zu schaffen, der wirklich unter 1 MB liegen muss. Während dies immens hilft, gibt es immer noch das Problem der FIXED-Blöcke. Der globale Heap-Manager ist nicht in der Lage, FIXED-Blöcke zu verschieben, sodass alle Blöcke, die kleiner als 1 MB sind, wenn ihnen das FIXED-Attribut zugewiesen wird, dort verbleiben. Es sind diese FIXED-Blöcke, die den Speicher unter 1 MB aufsaugen und es unmöglich machen, eine neue Aufgabe zu starten.

Also, wie bekommt man FIXED Speicherblöcke? Es gibt drei Möglichkeiten. Erstens können Sie Speicher mit GlobalAlloc zuweisen und ihm das GMEM_FIXED-Flag geben. Windows ignoriert das GMEM-FIXED-Flag, wenn die Zuordnungsanforderung von EXE-Code stammt, berücksichtigt es jedoch, wenn die Zuordnungsanforderung von einer DLL stammt. Zweitens können Sie die Segmente Ihrer EXE- oder DLL-Datei mit dem FIXED-Attribut markieren. Aus einem inzwischen veralteten Grund machen einige Linker standardmäßig Segmente FIXED. (Die Lösung besteht darin, die Segmentattribute explizit in der DEF-Datei festzulegen.) Wie bei GlobalAlloc ignoriert Windows das FIXED-Attribut beim Zuweisen von Speicher für EXE-Dateisegmente. Ein Segment in einer DLL hat das FIXED-Attribut, wenn die DLL FIXED für dieses Segment angibt.

Die dritte Möglichkeit, FIXED-Speicher zu erhalten, besteht darin, beweglichen Speicher zuzuweisen und ihm dann explizit das FIXED-Attribut zuzuweisen. Sowohl die GlobalFix- als auch die GlobalPageLock-Funktion geben Segmenten das FIXED-Attribut. (GlobalPageLock ruft zuerst GlobalFix auf und sperrt dann das Segment.) Diese Funktionen sind besonders gefährlich für den niedrigen MS-DOS-Speicher, da sie versuchen, den Block so weit wie möglich im Speicher nach unten zu schieben, bevor sie ihn reparieren. Dies kann dazu führen, dass Blöcke, die zuvor über 1 MB groß waren, nach unten in den 1-MB-Bereich verschoben werden, was das Problem weiter verschlimmert.

Wenn Sie die Notwendigkeit von Aufgabendatenbanken unter 1 MB mit der globalen Heap-Zuweisungsstrategie kombinieren, können Sie sehen, dass es in vielen Fällen zu Problemen kommen wird. Viele Gerätetreiber und System-DLLs erfordern FIXED und/oder Pagelocked-Speicher, da sie über Interrupt-Handler verfügen oder mit MS-DOS-Programmen im Realmodus kommunizieren. Dies gilt insbesondere für Netzwerktreiber. Da die meisten dieser Treiber früh im Windows-Startvorgang geladen werden, können Sie sehen, wie eine beträchtliche Menge des für TDBs erforderlichen Real-Mode-MSDOS-Speichers verbraucht werden kann. Leute sagen mir oft, dass sie, nachdem sie ein bestimmtes Programm gestartet haben, keine anderen mehr starten können. Dies liegt fast immer daran, dass das erste Programm einige DLLs oder Treiber verwendet, die das letzte Bit an Speicher unter 1 MB geschluckt haben.

In Windows 95 verschwindet dieses Problem größtenteils. Windows 95 ändert die Funktionsweise von GlobalAlloc so, dass (größtenteils) FIXED-Blöcke nicht unter 1 MB zugewiesen werden. Wenn es unter Windows 95 ausgeführt wird, zeigt mein Below1MB-Programm nur sehr wenige FIXED-Blöcke von Treibern und DLLs, die Speicherplatz unter 1 MB belegen. Darüber hinaus müssen Aufgabendatenbanken in Windows 95 nicht unter 1 MB liegen. Die PSP wurde jedoch aus der Windows 95-Aufgabendatenbank herausgelöst und muss immer noch unter 1 MB liegen. Um dies zu testen, habe ich mein ursprüngliches Below1MB-Programm leicht modifiziert, um den gesamten Speicher in Blöcken von 0x120 Bytes (der Größe einer PSP in Windows 95) zuzuweisen. 1 führte dieses modifizierte Unter 1 MB unter Windows 95 (M8 Preview-Build) aus und ließ es den gesamten Speicher unter 1 MB zuweisen. Ich habe dann versucht, ein neues Programm zu starten. Wie ich vermutete, startete Windows 95 die neue Aufgabe nicht,

Das Fix1MB-Programm

-----------------------------------------------------------------------------


Um das Problem des unzureichenden Arbeitsspeichers unter 1 MB zu lösen, habe ich das Fix1MB-Programm geschrieben (siehe Abbildungen 1 und 2). Fix 1MB sind wirklich zwei, zwei-zwei Programme in einem. Der erste Teil analysiert die globalen Heap-Blöcke unterhalb von 1 MB und gibt Ihnen eine Liste mit Speicherblöcken, die möglicherweise unnötig Speicherplatz beanspruchen. Zusammen mit jedem Block benennt der Bericht die EXE- oder DLL-Datei, die den Speicherblock besitzt. Mit diesen Informationen bewaffnet, kennen Sie zumindest die Hauptschuldigen am Diebstahl Ihres geringen Gedächtnisses. Basierend auf diesem Wissen entscheiden Sie sich möglicherweise dafür, einen bestimmten Gerätetreiber oder ein bestimmtes Programm zu entfernen. Möglicherweise können Sie sogar den Hersteller des betreffenden Programms oder Treibers dazu drängen, Ihnen eine aktualisierte Version zu geben, die FIXED-Segmente nicht unnötigerweise verwendet.

Der andere Teil von Fix1MB tut tatsächlich etwas gegen das Problem unter 1 MB. Mit ausgefeilten Techniken, die gemeinsam mit NASA-Wissenschaftlern entwickelt wurden, schützt es die Stelle, an der die meisten FIXED-Speicherblöcke unter 1 MB tauchen und sich dauerhaft niederlassen. Indem die Tür zum Speicher in einem kritischen Moment unter 1 MB geschlossen bleibt, zwingt Fix1MB Programme und Treiber dazu, ihre FIXED-Speicherblöcke woanders hin zu nehmen. (Dies ist die Windows-Version von „Not in my backyard.“)

Wenn Sie das Fix1MB-Programm in Windows ausführen, hindert es alle nachfolgend geladenen EYES und DLLs daran, FIXED-Blöcke unter 1 MB zu erfassen (mit einigen geringfügigen Ausnahmen, die ich später beschreiben werde). Obwohl dies in vielen Fällen helfen sollte, kann Ihr Problem mit Treibern und DLLs zusammenhängen, die beim Start geladen werden (z. B. Netzwerktreiber). Das Ausführen von Fix1MB kann in dieser Situation normalerweise nicht helfen. Diese Treiber lagern bereits unterhalb der 1-MB-Tür, wenn Fix1MB startet. Indem Fix1MB jedoch früh genug in der Startsequenz geladen wird, kann es normalerweise verhindern, dass die störenden Treiber und DLLs erhebliche Mengen an FIXED-Speicher unter 1 MB an sich reißen. Daher verfügt Fix1MB über eine Option, die es ermöglicht, es an einer strategischen Stelle in der Datei SYSTEM.INI zu platzieren, sodass es jedes Mal, wenn Sie Windows booten, relativ früh in der Startsequenz geladen wird. (Dies ist n' Es ist nicht so einfach, Fix1MB in die Autostart-Gruppe zu setzen. Wie es tatsächlich funktioniert, beschreibe ich später.) Damit das Laden der SYSTEM.INI funktioniert, müssen sich sowohl FIX1MB.EXE als auch FX1MBDLL.DLL im selben Verzeichnis befinden. PROCHOOK.DLL sollte sich auch im selben Verzeichnis oder irgendwo auf dem Pfad befinden.

Abbildung 1

Abbildung 1 zeigt, wie Fix1MB aussieht. Das Feld „Potential Free Space“ auf der oben zeigt, wie viel Speicher unter 1 MB verfügbar ist. Diese Figur ist nicht das, was ist zurzeit frei. Vielmehr ist es das, was kostenlos wäre, wenn Windows sich zurückziehen würde alle Anschläge, um sich im Speicher zu bewegen und den Speicherplatz unter 1 MB zu maximieren.

Das Listenfeld Potenzielle Speicherfresser ist eine nach Größe sortierte Liste von Speicherblöcken unter 1 MB, die nicht verschoben werden können. Diese Blöcke nehmen Platz unter 1 MB ein. Jede Zeile enthält eine Blockgröße, wofür der Block verwendet wird und den Besitzer des Speicherblocks. Fix1MB zeigt keine Blöcke an, für die Sie nichts tun können. Beispielsweise verwendet KRNL386.EXE (die Hauptsystem-DLL) ziemlich viel festen Speicher unter 1 MB. Aber da Sie nichts dagegen tun können, warum zeigen Sie es? Da es so gut wie unmöglich wäre, jede mögliche System-DLL herauszufiltern, zielt Fix1MB nur auf die Biggies ab (die tatsächliche Liste befindet sich in der Quelldatei FIX1MB.C). Wenn sich ein Block im Listenfeld „Fix1MB“ befindet, kann es sich um einen schlecht geschriebenen Treiber oder eine schlecht geschriebene DLL handeln, der berechtigte Speicherbedarf unter 1 MB hat oder eine System-DLL, die Sie nicht loswerden können. Zu einem gewissen Grad, Sie müssen sich die Liste ansehen und ein Urteil darüber fällen, ob Sie versuchen sollten, etwas gegen eine bestimmte Zeile zu unternehmen oder nicht. Oft kann es ausreichen, nur den Haupttäter (falls vorhanden) aufzuklären, um Sie wieder in Gang zu bringen.

Die Rewalk-Schaltfläche bewirkt, dass Fix1MB seine Analyse des Speichers unter 1 MB wiederholt. Immer wenn Sie Fix1MB aus einem symbolisierten Zustand wiederherstellen, wiederholt es seine Analyse. Wenn jedoch Programme oder DLLs geladen werden, während sich Fix1MB im nicht symbolisierten Zustand befindet, wird die Analyse von Fix1MB nicht mehr synchron sein. Um einen aktuellen Bericht zu erhalten, klicken Sie auf die Schaltfläche Rewalk.

Die Verwendung des Hilfe-Buttons sollte offensichtlich sein. Die verbleibende Schaltfläche in Fix1MB ist FIX1MB zu SYSTEM.INI hinzufügen. Dadurch fügt FIX1MB.DLL FX1MBDLL.DLL in die Zeile "drivers=" in SYSTEM.INI ein. Sobald Sie dies getan haben, führen nachfolgende Tastendrücke zu einer Fehlermeldung. Das Kontrollkästchen ganz unten ändert die Art und Weise, wie FIX1MB den Speicher unter 1 MB schützt. Standardmäßig ist es deaktiviert, was eine optimale Leistung ergibt. In einigen seltenen Fällen schützt die Standardeinstellung jedoch möglicherweise nicht ausreichend den niedrigen Speicher, sodass der Fehler „Nicht genügend Speicher“ zurückgegeben wird. Versuchen Sie in diesem Fall, das Kontrollkästchen zu aktivieren.

Unter der Haube von Fix1MB

-----------------------------------------------------------------------------


Wie ich bereits erwähnt habe, ist Fix1MB wirklich zwei Programme in einem. Wenn Sie sich nicht für die Heap-Analyse und meine minimalistische Benutzeroberfläche interessieren, können Sie diese Teile des Codes einfach extrahieren und neu kompilieren. Dennoch ist Fix1MB, ​​wie es jetzt existiert, ziemlich klein und hilft bei der Bestimmung, welche neue Low-Memory-Guarding-Technologie hat.

Der Low-Heap-Analyseteil von Fix1MB ist ziemlich unkompliziert und hat sich gegenüber BELOW1MB.EXE nicht wesentlich geändert. Die Ergebnisse, die Fix1MB zeigt, sehen jedoch ganz anders aus und sind viel klarer. Die WalkHeap-Funktion in FIX1MB.C durchläuft die globalen Heap-Blöcke bis zum Adresslimit von 1 MB, indem sie die ToolHelp-Funktionen GlobalFirst und GlobalNext verwendet. Während Fix1MB jeden Block durchläuft, sucht es nach zwei Dingen. Zuerst sucht es nach Heap-Blöcken, die nicht verschoben werden können und über die der Benutzer möglicherweise eine gewisse Kontrolle hat. Zweitens sucht Fix1MB nach Lücken zwischen dem Ende eines FIXED-Blocks und dem Beginn eines anderen. Die Gesamtgröße all dieser Lücken wird als freier Speicher gezählt, auch wenn der Platz gerade von einem verschiebbaren Block belegt ist. Wenn Windows wirklich Speicher unter 1 MB benötigt (z. B. für einen GlobalDosAlloc-Aufruf),

Wenn die WalkHeap-Routine jeden Block findet, ruft sie die IsPotentialSpaceHog-Funktion auf, die den Status des Blocks bestimmt. Wenn IsPotentialSpaceHog TRUE zurückgibt, landet der Block im Listenfeld Fix1MB. IsPotentialSpaceHog wirft sofort freie Blöcke und Sentinel-Blöcke aus (die KRNL386 verwendet, um Regionen des globalen Heaps zu markieren). IsPotentialSpaceHog wirft auch Blöcke aus, die nicht das GMEM_FIXED-Attribut haben und nicht seitengesperrt sind. (Pagelocked ist eine Obermenge des FIXED-Attributs. Alle Blöcke, die diese Tests bestehen, sind unbeweglich. An diesem Punkt sucht IsPotentialSpaceHog nach einer Lücke zwischen diesem Block und dem vorherigen unbeweglichen Block, und wenn es eine gibt, fügt sie sie dem Lauf hinzu gesamt. Bevor TRUE zurückgegeben wird, IsPotentialSpaceHog überprüft, ob der Block eine Aufgabendatenbank ist oder einer System-DLL gehört, über die der Benutzer keine Kontrolle hat. Wenn dies der Fall ist, gibt IsPotentialSpaceHog FALSE zurück, um zu verhindern, dass WalkHeap den Block in das Berichtslistenfeld einfügt.

Das andere Unterprogramm mit Fix1MB ist etwas komplizierter. Sein grundlegendes Ziel ist es, den gesamten (oder den größten Teil) Speicher unter 1 MB zuzuweisen, bevor der Windows-Loader oder ein Programm versucht, FIXED-Speicher zuzuweisen. Indem unter 1 MB kein Speicher frei gemacht wird, landet die FIXED-Speicherzuordnung weiter oben im Adressraum (denken Sie daran, dass der globale Heap-Manager in den meisten Fällen von unten nach oben nach freien Blöcken sucht). Nachdem der FIXED-Speicher irgendwo anders als unter 1 MB zugewiesen wurde, gibt Fix1MB den zuvor zugewiesenen Speicher frei.

Fix1MB weiß aufgrund der LoadModule-Routine, wann große FIXED-Speicherzuordnungen auftreten werden. LoadModule ist der zentrale Windows-Loader. Die meisten Zuweisungen von FIXED-Speicher werden innerhalb von LoadModule vorgenommen, wenn es Speicher für die Code- und Datensegmente von EXEs, DLLs und Gerätetreibern zuweist. Um einen signifikanten Effekt zu erzielen, muss Fix1MB lediglich verhindern, dass LoadModule seinen FIXED-Speicher unter 1 MB zuweist. Was ist mit anderen Routinen, die Programme und DLLs laden? Fix1MB deckt diese Grundlagen ab. LoadLibrary und WinExec sind beide Wrapper um einen Aufruf von LoadModule. Die ShellExecute-Funktion ist ein Wrapper um WinExec. Indem es beobachtet, wann LoadModule aufgerufen wird, kann Fix 1MB vier Fliegen mit einer Klappe schlagen.

Fix1mb überwacht, wenn LoadModule aufgerufen wird, indem es PROCHOOK.DLL von James Finnegan aus der MSJ-Ausgabe vom Januar 1994 verwendet. Ich habe kurz über die Verwendung von Breakpoints diskutiert, um Fix1MB vollständig in sich geschlossen zu halten, aber die Benutzerfreundlichkeit von ProcHook hat am Ende gewonnen. Fix1MB installiert einen Hook auf LoadModule und gibt Fix1MBLoadModule in FIX1MB.C als Callback-Funktion an. Innerhalb von Fix1MBLoadModule hebt der Code vorübergehend den LoadModule-Rückruf auf, weist den gesamten Speicher unter 1 MB zu und ruft dann das ursprüngliche LoadModule auf. Nach der Rückkehr von LoadModule gibt Fix1MBLoadModule den gesamten zuvor zugewiesenen Speicher frei und installiert dann den LoadModule-Hook neu. Durch den direkten Aufruf von LoadModule weiß Fix1MB implizit, wann es sicher ist, den zugewiesenen Speicher freizugeben. Dies wäre schwieriger zu bestimmen, wenn der Hook den Aufruf einfach mit dem ursprünglichen Handler verkettet hätte. Zusätzlich, LoadModule ist rekursiv, sodass Fix1MB alle verschachtelten Aufrufe von LoadModule ignorieren kann, wenn der Callback ausgehängt und LoadModule direkt aufgerufen wird. Auf diese Weise führt Fix1MB nur die Zuordnungen beim primären Aufruf von LoadModule durch und muss nichts für die verschachtelten LoadModule-Aufrufe tun.

Wenn der gesamte Speicher unter 1 MB zugewiesen wird, speichert Fix1MB die Blöcke in einer verknüpften Liste. Das erste WORD jedes zugewiesenen Blocks enthält das Handle des nächsten zugewiesenen Blocks. AllocTiledBelow1MBMemory weist Speicher unter 1 MB zu, indem GlobalDosAlloc aufgerufen wird. Um den Speicher unter 1 MB schnell zu erschöpfen, weist die Funktion 32-KB-Blöcke in einer Schleife zu, bis GlobalDosAlloc fehlschlägt. Dann halbiert AllocTiledBelow1MBMemory die Blockgröße und springt zurück zum Anfang der Schleife. Dies wird fortgesetzt, bis alle Blöcke mit mehr als 0x200 Bytes zugewiesen wurden. (Denken Sie daran, dass 0x200 Bytes die Größe einer Aufgabendatenbank ist. Nachdem alle Blöcke mit mehr als 0x200 Bytes zugewiesen wurden, gibt die Funktion den ersten Block in der Liste frei. Dadurch erhält LoadModule mindestens einen Block mit ausreichender Größe, um eine Aufgabendatenbank zu erstellen.

Es ist wichtig zu beachten, dass dieser Algorithmus nicht narrensicher ist. Beispielsweise könnten Sie ein Szenario haben, in dem nach den Zuweisungen der globale Heap unter 1 MB nur einen freien Block mit einer Länge von 0 x 200 Bytes hat. Wenn eine EXE (oder eine ihrer DLLs) ein FIXED-Segment mit 0x200 Bytes oder weniger hat, wird dieser Block für das Segment zugewiesen, und es bleibt kein Platz mehr für eine neue Aufgabendatenbank. In solchen Situationen schlägt die Aufgabenerstellung mit der Meldung "Nicht genügend Arbeitsspeicher zum Ausführen dieses Programms" fehl. Eine Lösung, die in diesem Fall normalerweise funktioniert, besteht darin, allen niedrigen MS-DOS-Speicher in Blöcken von 0x200 Bytes zuzuweisen und dann jeden zweiten Block freizugeben. Dies sollte viele Blöcke hinterlassen, die groß genug für eine Aufgabendatenbank sind. Leider verschlingt die Zuweisung so vieler kleiner Blöcke viele Selektoren und verlangsamt die Ladezeit des Programms merklich. Aus diesem Grund ist dies nicht das standardmäßige Zuordnungsschema. Sie können Fix1MB jedoch zwingen, diese Methode zu verwenden, indem Sie auf das Kontrollkästchen "Worst-Case-Modus" klicken.

Eine weitere Lücke in den Fix1MB-Programmen ist dynamisch zugewiesener Speicher. Ein Programm kann beweglichen Speicher mit GlobalAlloc und dann GlobalFix oder GlobalPageLock zuweisen. Da Fix1MB diese Aufrufe nicht überwacht, könnte KRNL386 den Block unter 1 MB verschieben, wenn Fix1MB nicht sucht. Nach meinen Beobachtungen ist Speicher, der auf diese Weise FIXED ist, selten der Hauptnutzer von Speicher unter 1 MB. Wenn Sie diese Lücke schließen möchten, können Sie zusätzliche ProcHook-Callbacks für GlobalFix und GlobalPageLock hinzufügen und das Zuweisungs-/Aufhebungsschema verwenden, das ich für LoadModule verwende.

Ein interessantes Problem beim Schreiben von Fix1MB war, was mit DLLs und Treibern zu tun ist, die früh in der Startsequenz geladen werden. Da diese DLLs eintreffen, bevor Fix1MB von der Startup-Gruppe von PROGMAN gestartet werden konnte, war ein wenig taktische Planung erforderlich. Durch Studieren der Modulliste von Windows (die in Modulladereihenfolge geführt wird) konnte ich die erste DLL finden, die über einen Eintrag in der Datei SYSTEM.INI geladen wurde. In meinem Fall war es MMSYSTEM.DLL, das sich in der Zeile "drivers=" im Abschnitt [boot] von SYSTEM.INI befindet. Mein erster Ansatz bestand darin, FIX1MB.EXE vor MMSYSTEM.DLL in die Zeile "drivers=" einzufügen. Leider hat dies nicht funktioniert. Windows hat sich geweigert, die ausführbare Datei zu laden (anscheinend will es nur DLLs in dieser Zeile laden). Mein zweiter Gedanke war, den Fix1MB-LoadModule-Hooking-Code in eine DLL zu packen. Allerdings habe ich Sie möchten nicht zwei Versionen desselben Basiscodes erstellen. Schließlich hatte ich die Idee, eine kleine DLL zu erstellen, die einfach WinExec Fix1MB.EXE in der LibMain der DLL enthalten würde. Da ich dachte, dass ich nichts zu verlieren hatte, versuchte ich es. Zu meiner Überraschung hat es funktioniert! So wurde FX1MBDLL.DLL geboren.

Wenn Fix1MB über FX1MBDLL.DLL geladen wird, kann die verfügbare Speichermenge unter 1 MB deutlich erhöht werden. In meiner Maschine (die nur ein paar Gerätetreiber hat) sparte mir das Laden von Fix1MB über SYSTEM.INI immer noch ungefähr 80 KB. Ich würde erwarten, dass es bei stärker belasteten Maschinen noch mehr sparen würde. Als weiteren Test habe ich WinFax Pro 3.0 (die neueste Version, die ich habe) gestartet, sowohl mit als auch ohne Fix1MB. Ohne Fix1MB nahm das Starten von WinFax Pro 71 KB aus meinem Speicher unter 1 MB. Mit Fix1MB benötigte WinFax Pro nur 2 KB.

Was passiert, wenn schlecht geschriebene Programme durch die Verwendung von Fix1MB kaputt gehen? Diese Probleme wären auf eine fehlerhafte Annahme im anderen Programm zurückzuführen, nicht auf einen Fehler in Fix1MB. Zuvor habe ich beschrieben, wie Segmente ausführbarer FIXED-Dateien häufig unter 1 MB zugewiesen werden. Einige Programme benötigen Speicher, auf den MS-DOS zugreifen kann (unter 1 MB) und gehen davon aus, dass ihre FIXED-Segmente immer unter 1 MB liegen. Obwohl dies normalerweise der Fall ist (zumindest nicht, wenn Fix1MB nicht läuft), ist es nicht unbedingt erforderlich. Da Fix1MB die meisten FIXED-Segmente über 1 MB zwingt, werden Programme, die auf FIXED-Speicher von unter 1 MB angewiesen sind, eine große Überraschung erleben. Die richtige Möglichkeit für diese Anwendungen, ihren Speicher zuzuweisen, wäre die Verwendung von GlobalDosAlloc.

Ich habe darüber nachgedacht, Fix1MB um eine "Hall of Shame"-Funktion zu erweitern. Die Funktion würde erkennen, wenn LoadModule im Begriff ist, eine dieser fehlerhaften Apps zu laden, und sich vorübergehend selbst deaktivieren. Obwohl es eine coole Idee ist, wollte ich nicht, dass Fix1MB zu groß wird. Ich mag es nicht, Anpassungen für fehlerhafte Apps vorzunehmen. Ich möchte lieber, dass sie ausgespült und durch funktionierende Versionen ersetzt werden. Wenn Fix1MB dazu führt, dass sich eine bestimmte Anwendung seltsam verhält oder abstürzt, versuchen Sie, Fix1MB zu beenden, bevor Sie die betreffende Anwendung starten.

[Abbildung 1 Fix1MB ILLUSTRATION AUSGELASSEN]
[Abbildung 2 FIX1MB]
[PROGRAMMLISTE AUSGELASSEN]

Codeblock:

Derzeit gibt es 39 klassische Banner, haben Sie schon alle gesehen?
Werbung

< Zurück ^ Nach oben EXIT Neue Seite

=============================================================================

Besucher Nummer: ERROR

Copyright © 2012-2024 retrospace.net

=============================================================================