Es ist lange her, dass ich dieses Zeug gelernt habe, aber jetzt geht es los.
Wenn ein Betriebssystem einen Prozess startet, weist es ihm Seiten aus der virtuellen Speichertabelle zu. Das Betriebssystem ist für die Verwaltung einer Zuordnung von der virtuellen Speichertabelle zum realen Speicher oder zum Auslagerungsspeicher auf der Festplatte verantwortlich. Wenn ein Prozess beendet wird, gibt das Betriebssystem ihm nicht nur keine CPU-Zyklen mehr. Es werden einige Bereinigungselemente ausgeführt, von denen eines darin besteht, alle Speicherseiten als frei zu markieren. Dadurch können sie von anderen Anwendungen wiederverwendet werden. Das Betriebssystem wird wahrscheinlich auch alle Ressourcen-Handles bereinigen, über die der Prozess verfügte, und dabei automatisch Dateien, Netzwerkverbindungen, Prozess-zu-Prozess-Pipes usw. schließen. Dieser Prozess unterliegt vollständig der Kontrolle des Betriebssystems und diese Schritte werden durchgeführt, unabhängig davon, wie der Prozess beendet wurde.
Beachten Sie, dass all dies für Betriebssystemprozesse gilt. Wenn Sie über eine virtuelle Maschine verfügen, auf der mehrere virtuelle Prozesse gleichzeitig ausgeführt werden, muss die VM entscheiden, wie sie zugewiesen und freigegeben werden soll. Vom Betriebssystem aus sieht es jedoch immer noch wie ein Prozess aus. Wenn Sie also in diesem Fall über eine VM verfügen, auf der mehrere Prozesse ausgeführt werden, und eine davon innerhalb der VM beenden, wird der Arbeitsspeicher im Host-Betriebssystem wahrscheinlich nicht sofort wieder verfügbar sein. Aber Sie werden es in der VM zurückbekommen. Wenn Sie jedoch die VM innerhalb des Betriebssystems beenden, wird das Betriebssystem die VM beenden (wodurch indirekt die Prozesse der VM beendet werden) und den gesamten Speicher zurückfordern (der nicht durch einen Garbage Collector gehen muss, free () , löschen oder irgendetwas anderes).
Sehr spekulativ:
Wenn .NET als virtuelle Maschine mit mehr als einer .NET-App auf derselben VM ausgeführt wird, kann .NET den Speicher behalten, der noch nicht GCd ist, bis der GC ausgeführt wird, und Windows würde annehmen, dass .NET dies ist mit mehr als es wirklich ist. (Und wenn MS wirklich schlau war, konnte Windows .NET in Situationen mit knappem Arbeitsspeicher an GC weiterleiten, aber das hat fast keinen Sinn, denn dafür ist der Speicherplatz für den Festplattentausch vorgesehen.)
Wenn .NET auf diese Weise funktioniert, würde das Betriebssystem es immer noch als einen Prozess für Betriebssystemzwecke betrachten, der die Verantwortung für die Entscheidung übernimmt, was aufbewahrt und weggeworfen werden soll, und es ist normalerweise nicht das Problem von Windows, einen Prozess zu bestimmen, den es benötigt um die Zuordnung des Speichers aufzuheben. Zu diesem Zeitpunkt ist es denkbar, dass MS eine spezielle API nur für .NET erstellt, sodass .NET-Prozesse wie Windows-Prozesse aussehen, außer dass dies nicht der Fall ist. Daher wird möglicherweise angenommen, dass die Zuordnung des Prozessspeichers nicht aufgehoben wurde. Es ist wirklich; Es ist nur so, dass Sie den falschen Prozess betrachten.
Ich weiß nicht genug über .NET, um zu sagen, dass es tatsächlich so funktioniert. die Java VM sicherlich nicht.
Ende der Spekulation.
BEARBEITEN: Wenn es darum geht, einen Prozess zu beenden, der für die Speicherverwaltung schlecht ist, müssen mehrere Prozesse aus demselben Pool zugeordnet werden (dh sie ähneln eher Threads als realen Prozessen) und der Speicher muss nach dem Prozess nicht freigegeben werden getötet. Dies würde beinahe ein kooperatives Multitasking-System erfordern, da der virtuelle Speicher und das präventive Multitasking meines Wissens normalerweise zusammen implementiert werden (die VM ermöglicht es, Prozesse voneinander zu isolieren und zu verhindern, dass sie sich gegenseitig in den Speicher drängen). Durch den virtuellen Speicher ist es trivial, nach einem Prozess auf Betriebssystemebene zu bereinigen. Verschieben Sie einfach alle Seiten aus dem Pool des Prozesses in den kostenlosen Pool.