PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Speicherverbrauch von .NET-Programmen


dariegel
2009-03-21, 17:10:45
Tach auch,

wenn ich ein kleines .NET-Programm (vorzugsweise VB .NET) schreibe, sitzt das mit ca. 10-20 MB im Arbeitsspeicher. Wenn ich mir dann z.B. KeePass Password Safe (http://www.keepass.info) anschaue, kann ich meinen Augen nicht trauen: nur ca. 1 MB im Hintergrundbetrieb (also minimiert in den Tray).

Wie ist sowas möglich, zumal ja KeePass Password Safe eine um Längen komplexere Anwendung ist, als ich sie schreibe.

Natürlich habe ich mich mit der Thematik vor einiger Zeit ein wenig befasst und speicherrelevante Änderungen am Code umgesetzt, allerdings mit vernachlässigbaren Auswirkungen auf den Arbeitsspeicherbedarf.

Wie optimiert Ihr Eure .NET-Anwendungen hinsichtlich Ressourcenverbrauch? Gibt es empfehlenswerte Dokumente zur Thematik?

Und bitte keine Anti-.NET-Diskussion, mir ist schon klar, dass bspw. C++ ohne das Framework dahinter ressourcenschonender ist.

Bin gespannt. Danke.

Trap
2009-03-21, 17:21:11
Womit/wie hast du den Ressourcenverbrauch gemessen?

Im Taskmanager wird der Speicherverbrauch der .NET-VM angezeigt, nicht der deines Programms...

dariegel
2009-03-21, 17:25:54
Aber letztendlich ist das doch ausschlaggebend, oder nicht? Wenn die .NET-VM "drumherum liegt", dann zählt das doch mit? Oder verstehe ich Dich falsch? Ich gehe von der Release-EXE (ohne Visual-Studio-IDE und Debugging) aus.

"Gemessen" habe ich mit dem Windows-Taskmanager.

Tiamat
2009-03-21, 17:29:37
Das hängt auch immer davon ab, wieviel Bibliotheken man importiert.
Man kann ja auf dem Weg x.x.x; oder x.* importieren.

Monger
2009-03-21, 17:30:09
.NET Assemblies werden nunmal komplett in den Speicher geladen, sobald auch nur irgendwas daraus verwendet wird. Wenn du z.B. einen String verwendest, wird schonmal die gesamte System Assembly geladen.

Das heißt, dass bei den meisten .NET Anwendungen schonmal ein ordentlicher Anteil des .NET Standard Frameworks geladen wird, noch bevor dein Programm eine Zeile ausgeführt hat.

Das klingt jetzt erstmal nach unnötiger Platzverschwendung, lohnt sich aber im größeren Maßstab. Denn wenn du zehn verschiedene .NET Programme startest, teilen die sich immer noch die selben geladenen Assemblies.

Man darf auch nicht vergessen, dass der Garbage Collector darauf gedrillt ist, sehr verschwenderisch mit RAM umzugehen solange er frei ist (was ja auch sinnvoll ist, schließlich sind RAM Zugriffe weitaus schneller als Festplattenzugriffe) - wirklich sinnvoll beurteilen kann man also den Speicherbedarf eines Programmes erst dann, wenn das System am Limit arbeitet.

Da hat sich gegenüber der "Altwelt" in C++ und Konsorten vieles geändert. Dass man von der Prozessgröße unmittelbar auf den Speicherbedarf dieser Anwendung schließen kann, ist im .NET Umfeld (und anderen interpretierten Sprachen wie z.B. Java) nicht mehr gegeben.
Grundsätzlich gilt: solange dir die Performance nicht einbricht, ignorier den Speicherbedarf.

dariegel
2009-03-21, 17:33:33
.NET Assemblies werden nunmal komplett in den Speicher geladen, sobald auch nur irgendwas daraus verwendet wird. Wenn du z.B. einen String verwendest, wird schonmal die gesamte System Assembly geladen.

Das heißt, dass bei den meisten .NET Anwendungen schonmal ein ordentlicher Anteil des .NET Standard Frameworks geladen wird, noch bevor dein Programm eine Zeile ausgeführt hat.

Das klingt jetzt erstmal nach unnötiger Platzverschwendung, lohnt sich aber im größeren Maßstab. Denn wenn du zehn verschiedene .NET Programme startest, teilen die sich immer noch die selben geladenen Assemblies.

Man darf auch nicht vergessen, dass der Garbage Collector darauf gedrillt ist, sehr verschwenderisch mit RAM umzugehen solange er frei ist (was ja auch sinnvoll ist, schließlich sind RAM Zugriffe weitaus schneller als Festplattenzugriffe) - wirklich sinnvoll beurteilen kann man also den Speicherbedarf eines Programmes erst dann, wenn das System am Limit arbeitet.

Da hat sich gegenüber der "Altwelt" in C++ und Konsorten vieles geändert. Dass man von der Prozessgröße unmittelbar auf den Speicherbedarf dieser Anwendung schließen kann, ist im .NET Umfeld (und anderen interpretierten Sprachen wie z.B. Java) nicht mehr gegeben.
Grundsätzlich gilt: solange dir die Performance nicht einbricht, ignorier den Speicherbedarf.

Soweit sogut, wie erklärst Du Dir dann den geringen Speicherbedarf von KeePass PS? Optimierung bis zum Anschlag? Aber wie?

Monger
2009-03-21, 17:33:54
Das hängt auch immer davon ab, wieviel Bibliotheken man importiert.
Man kann man ja auf dem Weg x.x.x; oder x.* importieren.

In .NET ist das importieren kein "Importieren" im Sinne von C++. Der Quellcode der anderen Assemblies wird eben nicht in die selbe Exe gebacken.

Der Import importiert lediglich die Namespaces, und ist damit nur syntaktischer Zucker für den Programmierer. Du könntest auch gar nichts importieren, und dafür die Pfade immer ausschreiben. Codemäßig ändert sich dadurch gar nix.

Geladen werden die Klassen grundsätzlich immer erst zur Laufzeit bei der ersten Verwendung. Das heißt, je nachdem was der Anwender tut, kann es durchaus sein dass manche Assemblies in einer Software nie geladen werden - obwohl sie im Quellcode drinstehen.

Soweit sogut, wie erklärst Du Dir dann den geringen Speicherbedarf von KeePass PS? Optimierung bis zum Anschlag? Aber wie?
Wer weiß? Vielleicht verwenden sie einfach ein paar Assemblies nicht die du eben doch verwendest. Wer weiß das schon? Man sieht ja auch nicht immer, was hinter einem Windows Control so alles steckt. Ist letztendlich auch völlig irrelevant.

Trap
2009-03-21, 17:42:29
Soweit sogut, wie erklärst Du Dir dann den geringen Speicherbedarf von KeePass PS?
KeePass lädt keine .NET-VM...

Monger
2009-03-21, 19:25:11
KeePass lädt keine .NET-VM...

Jetzt mal ne ganz blöde Frage, aber wie genau unterbinden die das denn? In den Systemanforderungen ist ab Version 2.x nunmal das .NET Framework zwingend als Voraussetzung angegeben, deshalb gehe ich mal schwer davon aus dass es auch genutzt wird. Also wohl kein fertig gebackenes Kompilat (was ja mit etwas Mühe wohl auch geht).

Aber was konkret machen die denn dann ohne .NET Runtime?

Trap
2009-03-21, 19:42:52
Jetzt mal ne ganz blöde Frage, aber wie genau unterbinden die das denn? In den Systemanforderungen ist ab Version 2.x nunmal das .NET Framework zwingend als Voraussetzung angegeben
Ups, hab nur in die alte Version geguckt, da war es rein C++.

Es könnte die VM als 2. Prozess starten, mal in den Code gucken ob man auf die schnelle was findet.

dariegel
2009-03-22, 10:13:57
Ok, danke Euch. Das beruhigt mich schonmal. :)

#44
2009-03-22, 19:00:59
Also ich hatte jetzt ca 7k Speicherverbrauch, unabhängig davon ob im Tray oder nicht. (v 1.15)

TheGamer
2009-03-23, 08:30:03
Das liegt daran dass ein minimiertes .NET Programm den nicht gebrauchte Dinge (wie GUI z.B) auf die Festplatte auslagert. Darum sind es im minimierten Zustand weniger MB Verbrauch.

Monger
2009-03-23, 09:03:46
Das liegt daran dass ein minimiertes .NET Programm den nicht gebrauchte Dinge (wie GUI z.B) auf die Festplatte auslagert. Darum sind es im minimierten Zustand weniger MB Verbrauch.
Was??

Also, ich lass mich auf das Argument ein, dass die GUI keinen Speicher verbraucht wenn sie nicht sichtbar ist, weil die entsprechende Sicht dann einfach nicht initialisiert wird. Aber .NET lagert selbstständig ganz bestimmt nix auf Festplatte aus. Swappen tut einzig und allein das Betriebssystem.

TheGamer
2009-03-23, 09:38:21
Was??

Also, ich lass mich auf das Argument ein, dass die GUI keinen Speicher verbraucht wenn sie nicht sichtbar ist, weil die entsprechende Sicht dann einfach nicht initialisiert wird. Aber .NET lagert selbstständig ganz bestimmt nix auf Festplatte aus. Swappen tut einzig und allein das Betriebssystem.

Ja klar das Betriebssystem.

Habs evt unguenstig geschrieben.

Gast
2009-03-23, 11:56:51
Wenn du z.B. einen String verwendest, wird schonmal die gesamte System Assembly geladen.

System.String steckt in mscorlib, nicht in System.