2010-05-17 4 views
16

Ich habe eine einfache kleine Frage, die jemand, der weiß, in der Lage sein wird, leicht zu antworten, ich habe google gesucht, aber konnte die Antwort nicht finden.Werden .dll-Dateien einmal für jedes Programm oder einmal für alle Programme geladen?

Es gibt viele Programme, die gleichzeitig auf einem Computer laufen, und meine Frage ist: Wenn ein Programm eine DLL lädt, lädt es tatsächlich die DLL-Datei oder findet es den Speicher, in dem die DLL bereits geladen ist? Wird beispielsweise ws2_32.dll (winsock 2) für jedes Programm geladen, das winsock verwendet, oder wird es einmal geladen, und alle Programme, die es verwenden, verwenden dieselben Speicheradressen, um die Funktionen aufzurufen?

Antwort

18

Es ist einmal geladen und alle Programme teilen sich die gleiche In-Memory-Kopie des Codes. Es ist etwas kompliziert, aber für die schreibgeschützten Abschnitte der DLL (das heißt Code) verwendet der Betriebssystemlader eine Technik, die "Speicherzuordnung" genannt wird, um die DLL in den Adressraum des Prozesses abzubilden. Die Seiten werden nur einmal für alle Prozesse in den physischen Speicher geladen, auch wenn die Seite möglicherweise in ihrem virtuellen Adressraum einer anderen Adresse zugeordnet ist.

Jeder Prozess hat jedoch einen separaten Datenabschnitt (so dass globale Variablen nicht gemeinsam genutzt werden - es sei denn, Sie fragen explizit danach) und sie haben natürlich auch einen separaten Heap, so dass dynamisch zugewiesener Speicher nicht freigegeben wird.

+0

Ok danke, das macht Sinn. Ich musste nur wissen, ob ein Zeiger auf eine Funktion von einer DLL auf die gleiche Adresse zeigen würde, die von allen Programmen verwendet wird, die die Funktion verwendeten. – Nilbert

+2

Die Antwort auf diese Frage ist "Nein". Funktionszeiger sind Adressen in den Prozessen * virtueller Adressraum *, und das wird definitiv nicht zwischen Prozessen geteilt. Eine DLL kann an verschiedenen Adressen in verschiedenen Prozessen geladen werden, und daher wird die Adresse eines Funktionszeigers anders sein - obwohl dieselbe physikalische Seite verwendet wird. –

+0

Tatsächlich ist es sehr unwahrscheinlich, dass die Funktion in zwei verschiedenen Programmen dieselbe Adresse hat. Der Code der DLL wird nach allen ihm vorausgehenden Code-Segment-Beiträgen in den nächsten verfügbaren Adressraum abgebildet. In Secure Linux wird die Randomisierung der Ladeadressen verwendet (um zu verhindern, dass viri hartcodierte Adressen in Angriffen verwendet). Du schreibst kein Virus, oder? :-) – wallyk

5

Es hängt davon ab, was Sie mit "geladen" meinen.

Die DLL ist für die gemeinsame Verwendung von Code und Daten vorbereitet: Die meisten Windows-Umgebungen berücksichtigen die Shareability (durch Zuordnen der gleichen Speicherkopie des Codes in den Speicherbereich jedes Prozesses), um Speicher zu sparen.

Teil der "load" -Operation (aus Sicht des Prozesses) ist jedoch die Initialisierung der DLL: Dies wird separat in jedem Prozess mit eindeutigen Kopien der Datenbereiche durchgeführt, die für jeden Prozess privat sind.