109 votes

Réduire l'utilisation de la mémoire des applications .NET ?

Quelles sont les astuces pour réduire l'utilisation de la mémoire des applications .NET ? Considérons le programme C# simple suivant.

class Program
{
    static void Main(string[] args)
    {
        Console.ReadLine();
    }
}

Compilé dans libérer mode pour x64 et s'exécutant en dehors de Visual Studio, le gestionnaire de tâches rapporte ce qui suit :

Working Set:          9364k
Private Working Set:  2500k
Commit Size:         17480k

C'est un peu mieux si c'est compilé juste pour x86 :

Working Set:          5888k
Private Working Set:  1280k
Commit Size:          7012k

J'ai ensuite essayé le programme suivant, qui fait la même chose mais essaie de réduire la taille du processus après l'initialisation de l'exécution :

class Program
{
    static void Main(string[] args)
    {
        minimizeMemory();
        Console.ReadLine();
    }

    private static void minimizeMemory()
    {
        GC.Collect(GC.MaxGeneration);
        GC.WaitForPendingFinalizers();
        SetProcessWorkingSetSize(Process.GetCurrentProcess().Handle,
            (UIntPtr) 0xFFFFFFFF, (UIntPtr)0xFFFFFFFF);
    }

    [DllImport("kernel32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool SetProcessWorkingSetSize(IntPtr process,
        UIntPtr minimumWorkingSetSize, UIntPtr maximumWorkingSetSize);
}

Les résultats sur x86 * Communiqué de presse * en dehors de Visual Studio :

Working Set:          2300k
Private Working Set:   964k
Commit Size:          8408k

C'est un peu mieux, mais cela semble encore excessif pour un programme aussi simple. Existe-t-il des astuces pour rendre un processus C# un peu plus léger ? J'écris un programme qui est conçu pour fonctionner en arrière-plan la plupart du temps. Je fais déjà tout ce qui concerne l'interface utilisateur dans un fichier séparé. Domaine d'application ce qui signifie que les éléments de l'interface utilisateur peuvent être déchargés en toute sécurité, mais occuper 10 Mo lorsqu'ils sont juste en arrière-plan semble excessif.

P.S. Quant à savoir pourquoi je m'en soucierais, les utilisateurs (puissants) ont tendance à s'inquiéter de ces choses. Même si cela n'a pratiquement aucun effet sur les performances, les utilisateurs semi-techniques (mon public cible) ont tendance à faire des crises de nerfs à propos de l'utilisation de la mémoire des applications en arrière-plan. Même moi, je panique quand je vois qu'Adobe Updater prend 11 Mo de mémoire et je me sens apaisé par la touche apaisante de Foobar2000, qui peut prendre moins de 6 Mo même en jouant. Je sais que dans les systèmes d'exploitation modernes, ce genre de choses n'a pas vraiment d'importance sur le plan technique, mais cela ne veut pas dire qu'elles n'ont pas d'effet sur la perception.

14 votes

Pourquoi vous en soucier ? L'ensemble de travail privé est assez faible. Les systèmes d'exploitation modernes mettront en page sur le disque si la mémoire est inutile. On est en 2009. A moins que vous ne construisiez des choses sur des systèmes embarqués, vous ne devriez pas vous soucier de 10MB.

8 votes

Arrêtez d'utiliser .NET et vous pourrez avoir de petits programmes. Pour charger le cadre .NET, un grand nombre de grosses DLL doivent être chargées en mémoire.

2 votes

Les prix de la mémoire baissent de façon exponentielle (oui, vous pouvez commander un système informatique domestique Dell avec 24 Go de RAM maintenant). À moins que votre application n'utilise >500 Mo, l'optimisation est inutile.

45voto

Brian Rasmussen Points 68853

Les applications .NET ont une empreinte plus importante que les applications natives, car elles doivent toutes deux charger le moteur d'exécution et l'application au cours du processus. Si vous voulez quelque chose de vraiment ordonné, .NET n'est peut-être pas la meilleure option.

Cependant, gardez à l'esprit que si votre application est principalement en sommeil, les pages de mémoire nécessaires seront échangées hors de la mémoire et ne seront donc pas vraiment une charge pour le système en général la plupart du temps.

Si vous souhaitez que l'encombrement soit faible, vous devrez penser à l'utilisation de la mémoire. Voici quelques idées :

  • Réduisez le nombre d'objets et veillez à ne conserver aucune instance plus longtemps que nécessaire.
  • Soyez conscient de List<T> et les types similaires qui doublent la capacité en cas de besoin, car ils peuvent entraîner jusqu'à 50 % de gaspillage.
  • Vous pourriez envisager d'utiliser des types de valeur plutôt que des types de référence afin de forcer l'utilisation de plus de mémoire sur la pile, mais gardez à l'esprit que l'espace de la pile par défaut n'est que de 1 Mo.
  • Évitez les objets de plus de 85000 octets, car ils iront dans la LOH qui n'est pas compactée et peut donc facilement être fragmentée.

Il ne s'agit probablement pas d'une liste exhaustive, mais juste de quelques idées.

0 votes

Autrement dit, les mêmes types de techniques qui permettent de réduire la taille du code natif fonctionnent en .NET ?

0 votes

Je suppose qu'il y a un certain chevauchement, mais avec le code natif, vous avez plus de choix en ce qui concerne l'utilisation de la mémoire.

33voto

John Rudy Points 16436
  1. Vous pourriez vouloir vérifier la question de Stack Overflow Empreinte mémoire de l'EXE .NET .
  2. L'article du blog MSDN Ensemble de travail != empreinte mémoire réelle est une démystification de l'ensemble de travail, de la mémoire de processus et de la façon de calculer précisément votre consommation totale de mémoire vive.

Je ne dirai pas que vous devez ignorer l'empreinte mémoire de votre application - il est évident qu'il est souhaitable d'avoir une application plus petite et plus efficace. Cependant, vous devez tenir compte de vos besoins réels.

Si vous écrivez une application client standard Windows Forms et WPF destinée à être exécutée sur le PC d'un particulier et susceptible d'être l'application principale dans laquelle l'utilisateur opère, vous pouvez vous permettre d'être moins regardant sur l'allocation de mémoire. (Tant qu'elle est entièrement désallouée).

Cependant, pour répondre à certaines personnes ici qui disent de ne pas s'inquiéter à ce sujet : Si vous écrivez une application Windows Forms qui sera exécutée dans un environnement de services de terminal, sur un serveur partagé pouvant être utilisé par 10, 20 utilisateurs ou plus, alors oui, vous devez absolument tenir compte de l'utilisation de la mémoire. Et vous devrez être vigilant. La meilleure façon d'aborder ce problème est de bien concevoir les structures de données et de suivre les meilleures pratiques concernant le moment et le contenu de l'allocation.

17voto

JaredPar Points 333733

Une chose à prendre en compte dans ce cas est le coût de la mémoire du CLR. Le CLR est chargé pour chaque processus .Net et entre donc dans les considérations de mémoire. Pour un programme aussi simple/petit, le coût du CLR va dominer votre empreinte mémoire.

Il serait beaucoup plus instructif de construire une application réelle et d'en comparer le coût à celui de ce programme de base.

7voto

Donut Points 32892

Pas de suggestions spécifiques en soi, mais vous pourriez jeter un coup d'œil à l' CLR Profiler (téléchargement gratuit de Microsoft).
Une fois que vous l'avez installé, jetez un coup d'oeil à ceci page comment faire .

Du mode d'emploi :

Ce guide vous montre comment utiliser l'outil outil CLR Profiler pour étudier l'allocation d'allocation de mémoire de votre application de votre application. Vous pouvez utiliser CLR Profiler pour identifier le code à l'origine de problèmes problèmes de mémoire, tels que les fuites de mémoire et fuites de mémoire et la collecte excessive ou inefficace ou inefficace.

7voto

Eric Petroelje Points 40734

Vous devriez peut-être regarder l'utilisation de la mémoire d'une "vraie" application.

Comme pour Java, il y a une quantité fixe d'overhead pour le runtime, quelle que soit la taille du programme, mais la consommation de mémoire sera beaucoup plus raisonnable après ce point.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X