Meine kleinen Aufzeichnungen

14 Mai 2006

ASP.NET-Applikationen: warum debug="false"?

Warum ist folgende Aussage ernst zu nehmen?

Stellen Sie sicher, dass debug="false" im compile-Element der web.config-Datei für jede ASP.NET-Applikation auf dem Produktionsserver gesetzt ist. Während der Entwicklungsphase ist der Standardwert "true", was häufig dazu führt, dass diese Einstellung auch im Echtbetrieb beibehalten wird. Dieser Umstand kann führt zu ineffizientem Speicherverhalten.

Welche Probleme verursacht debug="true"?

Es gibt drei Unterschiede zwischen debug="true"/"false":
  • ASP.NET-Timeouts
  • Batch-Kompilierung
  • Code-Optimierung

1. ASP.NET Timeouts

Wenn debug auf "true" gesetzt wird, erhalten ASP.NET-Request keinen Timeout. Damit soll gewährleistet werden, dass Entwickler in Visual Studio in Ruhe ihre Applikation testen und debuggen könnnen, ohne ständig mit Timeouts konfrontiert zu werden. Natürlich sind Timeouts im Echtbetrieb ein unerlässliches Mittel, damit Anfragen nicht ewig hängenbleiben und Systemressourcen blockieren.

2. Batch-Kompilierung

Kurz gesagt, wenn debug="true" kann eine Batch-Kompilierung erfolgen, sonst nicht. Was bedeutet das?

Wenn eine aspx-, asax- oder ascx-Datei zum ersten Mail aufgerufen und in eine Assembly kompiliert wird, erhält sie einen in acht Zeichen kodierten Namen (z.B. 2nt0rgwd.dll or ähnlich). Diese temporäre Assembly wird für jede Datei der genannten Typen im Verzeichnis "C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\Temporary ASP.NET Files" + Applikationsname. Die Klasse, die aus dem "Code-Behind" resultiert, wird mit allen anderen DLLs aus dem bin-Verzeichnis als Schattenkopie in diesem temporären Verzeichnis abgelegt.
Zurück zur 2nt0rgwd.dll. Wenn debug="true", dann wird pro aspx, asax und ascx eine einzelne Datei erzeugt. Das heißt zum Beispiel, für 100 Dateien werden 100 DLLs erzeugt, und das zum Zeitpunkt, wenn die Seite oder das Control das erste Mal aufgerufen wird.
Wenn hingegen debug="false" gesetzt ist, erfolgt die Kompilierung als Batch, das heißt, das beim ersten Aufruf irgendeiner Seite in der Applikation die Gesamtheit aller Seiten und Controls in eine große DLL kompiliert wird. Diese Aussage ist noch ein wenig zu relativieren, denn ascx werden in eine getrennte Datei kompiliert und die aspx werden in Gruppen mit den Usercontrols, die sie inkludieren, kompiliert. Auch die global.asax-Datei wird in eine eigene Datei kompiliert. Außerdem geschieht die Kompilierung noch auf Verzeichnisebene, d.h. Unterverzeichnisse erhalten auch eigene Dateien. Aber im Großen und Ganzen ist die Anzahl anstatt 100 doch nur vielleicht 3 oder 4.
Was ist nun der Nachteil, wenn es viele DLLs sprich Assemblies gibt? Der Adressraum im Speicher wird wesentlich ungünstiger verwendet, sprich fragmentiert. Dieser Umstand bewirkt, dass es für die Laufzeitverwaltung von .NET schwieriger wird, geeignet große Blöcke auf dem Heap zu finden. Somit wird der Overhead und Speicherbedarf unnötig erhöht.
Etwas ist noch zu beachten. Wenn eine einzige aspx-Datei geändert wird, wird diese Datei extra kompiliert, damit nicht die gesamte App-Domain neu geladen werden muss. In der machine.config gibt es diesbezüglich eine Einstellung, in der festgehalten ist, wie viele derartige Änderungen maximal gemacht werden können, bis die App-Domain neu geladen wird, gerade so, als ob die web.config oder das bin-Verzeichnis geändert wurden.

3. Code-Optimierung

Damit man in der Entwicklungsphase fähig ist, Schritt für Schritt durch den Code zu gehen, ist in dieser Phase der JIT-Compilter (Just in Time) ausgeschalten. Die Code-Optimierung erfolgt also nur, wenn der Debug-Schalter auf "false" gesetzt ist.
Insgesamt also genügend Gründe, um diese wichtige Einstellung auf den Produktionssystemen richtig zu stellen.

Übrigens: In einem Speicherabbild (Memory Dump) kann identifiziert werden, ob die Applikation im Debug-Modus lief oder nicht. Das Kommando !finddebugtrue in der sos.dll listet alle Applikationen mit debug="true" in the web.config auf. Einfach, nicht?

In ASP.NET 2.0 gibt es einen Schalter in der machine.config, der alle debug="true" deaktiviert, so dass auf einem Produktionsserver alle Applikationen automatisch mit debug="false" laufen:


<configuration>
   <system.web>
      <deployment retail="true"/>
   </system.web>
</configuration>


Weitere Goodies zum Thema im Blogeintrag von Scott Guthrie.