2015-07-08 9 views
15

Ich bin auf der Suche nach weiteren Details, wann und wie .NET-Anwendungen geladene Assemblys teilen. Ich bin daran interessiert, zwischen OS-Prozessen, aber auch zwischen AppDomains innerhalb desselben Prozesses zu teilen. Das Teilen von Baugruppen reduziert die Systemspeicherauslastung, indem vermieden wird, mehrere Kopien derselben Baugruppe im Speicher zu haben. Ich nehme an, dass dies der Hauptvorteil ist, wäre aber daran interessiert zu wissen, ob es weitere Vorteile und/oder Implikationen gibt.Unter welchen Umständen teilen .NET-Prozesse und AppDomains geladene Assemblys im Arbeitsspeicher?

Eine Zusammenfassung von dem, was ich bisher ... kann

  1. Sysinternals process explorer gelernt haben, eine .NET-Prozess des AppDomains und die Baugruppen zur Liste verwendet werden, in jede AppDomain geladen.

  2. Ein .NET-Prozess scheint immer "Kern" -Assemblys in eine AppDomain namens "SharedDomain" zu laden (es ist anzunehmen, dass dies innerhalb des aktuellen Prozesses zwischen AppDomains geteilt wird).

  3. Task-Manager und Process Explorer Bericht nicht unerhebliche Speichernutzung Zahlen für ‚Working Set Geteilt‘ und ‚Working Set Shareable‘, aber es ist nicht klar, was geteilt wird. (Ist es die ‚Kern‘ Baugruppen innerhalb des Shared AppDomain? Sind andere [Nicht-Kern] Baugruppen auch geteilt?

  4. In einem einfachen Test startete ich zwei Kopien einer Standalone-NET-Anwendung und an ein Visual Studio-Debugger Die Ansicht "Module" zeigt die geladenen Assemblys und ihre Adressen im Speicher an. In meinem Testfall befand sich jedes geladene Modul an der gleichen Adresse in den beiden Prozessen. (Zeigt dies die gemeinsame Nutzung an, oder ist dies der virtuelle Adressraum, der dies nicht ist) notwendigerweise geteilt?)

  5. ASP.NET 4.5 Austausch von Baugruppen über einen Mechanismus Baugruppe interning genannt unterstützt (siehe Look at Sharing Common Assemblies in ASP.NET 4.5, Sharing Common Assemblies, Sharing common assemblies with aspnet_intern.exe). Es scheint, durch die Einrichtung von Dateisystem zu arbeiten, Symbolische Links (Symlinks), so dass verschiedene Web-Apps auf einen gemeinsamen Bin-Ordner verweisen, wirft daher die Frage auf, ob ASP.NET einfach Symlinks verwendet, um das Standardverhalten für die Baugruppenfreigabe in .NET auszulösen, oder ob ASP etwas Spezielleres ist .NET und IIS AppPools gehen weiter.

Hinweis.

C: auf einem Computer mit Visual Studio 2013 installiert haben, können aspnet_intern.exe in gefunden werden \ Program Files (x86) \ Microsoft SDKs \ Windows \ V8.1A \ bin \ netfx 4.5.1 Tools \

In späteren Versionen von .NET und Windows Server wurden die ASP.NET-Startzeit und die Speicherauslastung weiter verbessert. Siehe ASP.NET App Suspend – responsive shared .NET web hosting, Performance Improvements for ASP.NET Shared Hosting Scenarios in .Net 4.5, aber ich bin mir nicht sicher, wie relevant diese Änderungen für diese Frage sind.

ASP.NET Montage-Sharing ist auch in dem Buch Introducing .NET 4.5 bedeckt.

Auch fragen, ob JITted-Code freigegeben ist oder nicht, da eine geladene Assembly aus MSIL, Ressourcen, Metadaten usw. besteht und weiterer Speicher zugeordnet werden muss, wenn der Code JITted ist.

Es gibt auch diese Diskussion über Montage-Sharing im kompakten Rahmen (We Believe in Sharing, MSDN Blogs, Abhinaba Basu)

--- --- UPDATE

ich die sysinternals VMMap tool verwendet zwei AppPools zu untersuchen , eine mit asp.net Assembly internign eingerichtet, die andere ohne. Ich habe auch eine Testaspx-Seite berührt, um ASP.NET dazu zu bringen, alle Assemblys zu laden (und eine global.asax-Datei führt eine kleine Menge Code aus, was zu JITting führt).

Die ausgewiesenen Speichernutzungszahlen für die beiden AppPools sehr ähnlich ist, der Arbeitssatz, WS Privat und WS Shareable ist im Wesentlichen gleich. WS Shared ist jedoch im "Interning" AppPool viel größer. Dies war unerwartet (für mich), da es keinen anderen Prozess für die Freigabe gibt, aber VMMap zeigt die Speicherblöcke (markiert als '.text' und mit Execute/Read protection), die im AppPool zum Freigeben von Arbeitsspeicher angezeigt werden die gleiche Assembly im anderen AppPool teilt nicht. Meine Interpretation davon ist, dass Blöcke von virtuellem Speicher in dem Prozess auf denselben physischen Speicher abgebildet werden und dann als "WS Shared" gemeldet werden. Montage Space Layout Randomization

ASLR

Bezug. Das VMMap-Tool zeigt viele Speicherblöcke mit dem Typ 'Image (ASLR)' an. ASLR randomisiert den Speicherort von Assemblys im Speicher, um Malware zu vereiteln, und ich fragte mich, ob dies verhinderte, dass das Assembly Interning korrekt funktionierte. Das Deaktivieren von ASLR für die Maschine, die die EMET tool verwendet, führte dazu, dass die Assembly-Adressen regulär waren, aber die gemeldeten Speicher-Nummern nicht änderten, so scheint es, Assembly Interning nicht zu beeinträchtigen. Es ist erwähnenswert, dass VMMap immer noch Bilder mit "ASLR" gegen sie zeigte, was, wie ich vermute, einfach bedeutet, dass eine Assembly/ein Image als unterstützend/erlaubend für ASLR markiert ist, nicht dass ASLR in Kraft ist.

+1

Dieser Blog-Eintrag hat eine Menge Informationen. Es benutzt den Begriff 'Domain Neutral Assemblies' für das, was Sie beschreiben (ich glaube). http://blogs.msdn.com/b/junfeng/archive/2004/08/05/208375.aspx –

+0

Ich stimme zu öffnen, weil, obwohl es eine Menge etwas tangential verwandten Informationen in der Frage Text gibt, Die Frage selbst ist klar definiert und sehr eng gefasst. Es gibt nur sehr wenige Szenarios, in denen ein Betriebssystemprozess und/oder eine Anwendungsdomäne Baugruppen und Speicher mit anderen teilen. – redcalx

Antwort

1

Ein Fall, bei der Montage-Sharing erfolgt ist Baugruppen nativen Code mit ngen.exe zusammengestellt. Lassen Sie mich "CLR via C#" zitieren (Kapitel 1)

Das NGen.exe Werkzeug in zwei Szenarien interessant ist:

...

eine Anwendung Workingset Reduzierung - wenn Sie glauben, dass Eine Assembly wird gleichzeitig in mehrere Prozesse geladen. Durch das Ausführen von NGen.exe auf dieser Assembly kann der Arbeitssatz der Anwendungen reduziert werden. Der Grund dafür ist, dass das Tool NGen.exe die IL in nativen Code kompiliert und die Ausgabe in einer separaten Datei speichert. Diese Datei kann gleichzeitig in mehrere Prozess- -Adressräume gespeichert werden, sodass der Code gemeinsam genutzt werden kann. nicht jeder Prozess benötigt eine eigene Kopie des Codes.