11
votes

Gestion de la mémoire pour des applications intensifs intentionnellement de mémoire

Note: Je suis au courant de la question Gestion de la mémoire Dans une demande intensive de mémoire , cependant, cette question semble être sur les applications qui font des allocations de mémoire fréquentes, alors que ma question concerne des applications intentionnellement conçues pour consommer autant de mémoire physique que celles-ci.

J'ai une application de serveur utilisant de grandes quantités de mémoire afin d'effectuer la mise en cache et d'autres optimisations (Pensez SQL Server). L'application s'exécute sur une machine dédiée, et peut (et devrait donc (et devrait) consommer autant de mémoire qu'il veut / est capable de accélérer et d'augmenter les temps de débit et de réponse sans soucier d'avoir un impact sur les autres applications du système.

Le problème est que si l'utilisation de la mémoire est sous-estimée ou si la charge augmente sa possible pour se retrouver avec des défaillances méchantes, car les allocations de mémoire échouent - dans cette situation, la meilleure chose à faire est de libérer de la mémoire afin de prévenir l'échec au détriment de la performance.

Certaines hypothèses:

  • L'application est en cours d'exécution sur une machine dédiée
  • Les exigences de la mémoire de l'application dépassent la mémoire physique de la machine (c'est-à-dire si une mémoire supplémentaire était disponible pour l'application, il serait toujours en mesure d'utiliser cette mémoire à une manière d'une manière ou d'une autre améliorer les temps de réponse ou le débit)
  • La mémoire est gérée effectivement de manière à ce que la fragmentation de la mémoire ne soit pas un problème.
  • L'application sait quelle mémoire peut être libérée en toute sécurité et quelle mémoire devrait être libérée d'abord pour l'impact de la moindre performance.
  • L'application fonctionne sur une machine Windows

    Ma question est - Comment dois-je gérer les allocations de mémoire dans une telle application? en particulier:

    • Comment puis-je prédire si une allocation de mémoire échouera ou non?
    • Devrais-je laisser une certaine mémoire libre afin de garantir que les opérations de base du système d'exploitation restent réactives (et n'ont pas d'une incidence négative sur les performances des applications) et comment puis-je découvrir la quantité de mémoire qui est? < / li>

      L'objectif de base est de prévenir les échecs résultant de l'utilisation d'une trop grande mémoire tout en utilisant autant de mémoire que possible.

      Je suis un développeur C #, mais mon espoir est que les concepts de base pour une telle application sont les mêmes quelle que soit la langue.


1 commentaires

BTW - J'ai ému intentionnellement du terme "mémoire" en raison de la complexité de la mémoire physique virtuelle VS. Pour la même raison, je n'ai pas mentionné 32 bits vs 64 bits.


3 Réponses :


1
votes

sous Linux, le pourcentage d'utilisation de la mémoire est divisé en niveaux suivants.

0 - 30% - Aucun échange 30 - 60% - échanger des pages sales uniquement 60 - 90% - Pages propres d'échange également basées sur la politique de la LRU.

90% - invoquez OOM (hors de mémoire) tueur et tuez le processus consommant une mémoire maximale.

Vérifiez ceci - http://linux-mm.org/oom_killer

Dans Think Windows peut avoir une stratégie similaire, vous pouvez donc vérifier les statistiques de mémoire et vous assurer de ne jamais avoir au seuil maximum.

Un moyen d'arrêter de consommer plus de mémoire consiste à vous endormir et à donner plus de temps pour les fils de nettoyage de la mémoire à exécuter.


0 commentaires

0
votes

C'est une très bonne question et doit également être subjective, car la nature même du fondamental de C # est que toute la gestion de la mémoire est effectuée par le runtime, c'est-à-dire le collectionneur des ordures. Le Garbage Collector est une entité non-déterministe qui gère et balaie la mémoire pour récupérer, selon la fréquence de la mémoire est fragmentée, le GC botter donc de savoir à l'avance n'est pas chose facile à faire.

Pour gérer correctement la mémoire Son sons fastidieux, mais le bon sens ne s'applique, tel que la clause à l'aide de la clause pour assurer un objet éliminé. Vous pouvez mettre dans un seul gestionnaire pour piéger l'exception omphmemory mais qui est une manière maladroite, car si le programme est à court de mémoire, le programme est-il de saisir et de sortir, ou devrait-il Attendez patiemment que le GC soit lancé, déterminez à nouveau que c'est délicat.

La charge du système peut nuire au travail de la GC, presque à un point d'un déni de service, où tout se passe-t-il à une halte, à nouveau, depuis les spécifications de la machine, ou quelle est la nature de cette machine Le travail est inconnu, je ne peux pas répondre pleinement, mais je suppose que cela a des charges de RAM ..

En substance, alors une excellente question, je pense que vous ne devriez pas vous inquiéter et laisser le CLR .NET pour gérer l'allocation / fragmentation mémoire car il semble faire un très bon travail.

J'espère que cela aide, Meilleures salutations, Tom.


0 commentaires

0
votes

Votre question me rappelle une ancienne discussion "Alors qu'est-ce qui ne va pas avec la programmation de 1975?" / a>. L'architecte de Varnow-cache soutient que, au lieu de dire au système d'exploitation de sortir du chemin et de gérer Toute mémoire vous-même, vous devriez plutôt coopérer avec le système d'exploitation et laisser comprendre ce que vous avez l'intention de faire de la mémoire.

Par exemple, au lieu de simplement lire des données à partir de disque, vous devez utiliser Fichiers mappé sur mémoire . Cela permet au système d'exploitation d'appliquer son algorithme LRU aux données de rétablissement du disque lorsque la mémoire devient rare. Dans le même temps, tant qu'il y a suffisamment de mémoire, vos données resteront en mémoire. Ainsi, votre application peut potentiellement utiliser toute la mémoire, sans risquer de se faire tuer.


0 commentaires