60 votes

Un moyen de déterminer l'utilisation "réelle" de la mémoire d'un processus, c'est-à-dire un flux RSS sale privé?

Des outils comme 'ps' et 'top rapport des différents types de mémoire usages, tels que la taille de mémoire virtuelle et le Résident de la Taille de l'Ensemble. Cependant, aucune de ces sont les "vrais" l'utilisation de la mémoire:

  • Le code de programme est partagée entre plusieurs instances d'un même programme.
  • Bibliothèque partagée code de programme est partagée entre tous les processus qui utilisent la bibliothèque.
  • Certaines applications fork de processus et de partager de la mémoire avec eux (par exemple via les segments de mémoire partagée).
  • Le système de mémoire virtuelle rend la VM rapport de taille à peu près inutile.
  • RSS est de 0 lorsqu'un processus est échangé, ce qui n'est pas très utile.
  • Etc etc.

J'ai trouvé que le privé sale RSS, tel que rapporté par Linux, est la chose la plus proche à la "vraie" utilisation de la mémoire. Ceci peut être obtenu en additionnant tous Private_Dirty valeurs en /proc/somepid/smaps.

Cependant, d'autres systèmes d'exploitation fournissent des fonctionnalités similaires? Si non, quelles sont les alternatives? En particulier, je suis intéressé par FreeBSD et mac OS X.

50voto

Mecki Points 35351

Sur OSX le Moniteur d'Activité vous donne une très bonne estimation.

Privé de mémoire est pour vous assurer que la mémoire est uniquement utilisé par votre application. E. g. pile de mémoire et toute la dynamique de la mémoire réservée à l'aide de malloc() et comparables sur les fonctions/méthodes (méthode alloc pour Objective-C) est privé de la mémoire. Si vous fourche, privé de mémoire seront partagés avec votre enfant, mais marqué de copie sur écriture. Cela signifie que tant que la page n'est pas touché (et en disant toucher, je veux dire par écrit à, ne pas la lecture), soit par processus (parent ou enfant), il est partagé entre eux. Dès que le processus touche n'importe quelle page, cette page est copiée avant qu'il soit modifié. Même si cette mémoire est partagée avec une fourchette les enfants (et il peut seulement être partagé avec une fourchette enfants), il est toujours indiqué comme "privé" de la mémoire, parce que dans le pire des cas, chaque page de il obtiendra touché (tôt ou tard) et puis c'est à nouveau privé de chaque processus à nouveau.

La mémoire partagée est soit de la mémoire qui est actuellement partagée (les mêmes pages sont visibles dans le virtuel espace de processus de processus différents) ou qui est susceptible de devenir partagé dans le futur (par exemple, mémoire en lecture seule, car il n'y a aucune raison pour ne pas le partage de mémoire en lecture seule). Au moins c'est comment j'ai lu le code source de certains outils de ligne de commande à partir d'Apple. Donc, si vous partager la mémoire entre les processus à l'aide de mmap (ou comparables appel que les cartes de la même mémoire dans plusieurs processus), ce serait de la mémoire partagée. Toutefois, le code exécutable lui-même est également de la mémoire partagée, car si une autre instance de votre application est démarrée il n'ya aucune raison pourquoi il ne peut pas partager le code déjà chargé en mémoire (code exécutable pages sont en lecture seule par défaut, sauf si vous exécutez votre application dans un débogueur). Ainsi, la mémoire partagée est vraiment de la mémoire utilisée par votre application, tout comme le privé, mais il peut en outre être partagé avec un autre processus (ou peut être pas, mais pourquoi ne serait-il pas compter vers votre application si elle est partagée?)

La mémoire réelle est la quantité de RAM actuellement "attribué" à votre processus, peu importe si privative ou commune. Cela peut être exactement à la somme des privés et partagés, mais, habituellement, il n'est pas. Votre processus peut disposer de plus de mémoire affectée à elle qu'elle a besoin (ce qui accélère les demandes de plus de mémoire dans le futur), mais c'est pas une perte pour le système. Si un autre processus a besoin de la mémoire et pas de mémoire est disponible, avant le démarrage du système d'échange de fichiers, il faudra que la mémoire supplémentaire loin de vos processus et de l'affecter à un autre processus (ce qui est rapide et indolore de l'opération); à cet effet dans votre prochain appel de malloc peut-être un peu plus lent. La mémoire réelle peut aussi être plus petit que privé et de la mémoire physique; c'est parce que si votre processus de demande de la mémoire du système, il ne recevra de "mémoire virtuelle". Cette mémoire virtuelle est pas lié à une réelle pages de mémoire tant que vous ne l'utilisez pas (donc malloc 10 MO de mémoire, utilisez uniquement un octet, votre processus obtiendrez une seule page, 4096 octets, de la mémoire assignée - le reste n'est attribué que si vous avez réellement jamais besoin d'elle). Plus de la mémoire qui est échangé ne comptent pas dans la mémoire réelle soit (pas sûr à ce sujet), mais le calcul partagés et privés de la mémoire.

La mémoire virtuelle est la somme de tous les blocs d'adresses qui sont valables dans vos applications à l'espace de processus. Ces adresses peuvent être liés à la mémoire physique (qui est de nouveau privé ou partagé), ou peut-être pas, mais dans ce cas, ils seront liés à la mémoire physique dès que vous utilisez l'adresse. Accéder à la mémoire des adresses en dehors des adresses connues, va provoquer un SIGBUS et votre application crash. Lorsque la mémoire est échangé, l'espace d'adressage virtuel pour cette mémoire reste valable et l'accès à ces adresses causes de la mémoire pour être échangé en retour.

Conclusion:
Si votre application ne prend pas explicitement ou implicitement l'utilisation de la mémoire partagée, mémoire privée est la quantité de mémoire de votre application a besoin en raison de la taille de la pile (de taille ou si multithread) et en raison de la fonction malloc() appels que vous avez effectués pour la mémoire dynamique. Vous n'avez pas de soins beaucoup pour le partage ou la mémoire réelle dans ce cas.

Si votre application utilise la mémoire partagée, et cela inclut une INTERFACE utilisateur graphique, où la mémoire est partagée entre votre application et le WindowServer par exemple, alors vous pourriez avoir un coup d'oeil à mémoire partagée aussi bien. Une très grande mémoire partagée nombre peut signifier que vous avez trop de ressources graphiques chargé en mémoire à l'instant.

La mémoire réelle est de peu d'intérêt pour le développement d'applications. Si il est plus grand que la somme de communes et privées, alors cela ne signifie rien d'autre que ce que le système est paresseux à prendre de la mémoire à l'écart de votre processus. Si elle est plus petite, alors votre processus a demandé plus de mémoire que nécessaire, ce qui n'est pas mal non plus, car tant que vous n'utilisez pas la totalité de la mémoire demandée, vous n'êtes pas le "vol" de la mémoire du système. Si elle est beaucoup plus petite que la somme de communes et privées, vous ne pouvez envisager de demander moins de mémoire, si possible, que vous êtes un peu trop demander de la mémoire (encore une fois, ce n'est pas mauvais, mais il me dit que le code n'est pas optimisé pour une faible utilisation de la mémoire et si il est multi plate-forme, d'autres plates-formes peuvent ne pas avoir une telle sophistiqués de gestion de la mémoire, de sorte que vous pouvez préférer alloc de nombreux petits blocs au lieu de quelques grands, par exemple, ou de la mémoire libre beaucoup plus tôt, et ainsi de suite).

Si vous n'êtes toujours pas satisfait avec toutes ses informations, vous pouvez obtenir encore plus d'informations. Ouvrez un terminal et exécutez:

sudo vmmap <pid>

où est l'ID de processus de votre processus. Cela va vous montrer les statistiques pour CHAQUE bloc de mémoire dans votre espace de processus avec le début et la fin de l'adresse. Il vous indiquera également où cette mémoire est venu de (Un fichier mappé? La pile de la mémoire? Malloc ed de mémoire? Un _DATA ou _TEXTE de la section de votre exécutable?), comment elle est grande dans la base de connaissances, les droits d'accès et de savoir s'il est privé, partagé ou de copie sur écriture. Si il est mappé à partir d'un fichier, il va même vous donner le chemin d'accès au fichier.

Si vous souhaitez que seuls les "réels" de l'utilisation de la RAM, l'utilisation

sudo vmmap -resident <pid>

Maintenant, il va montrer pour chaque bloc de mémoire la taille du bloc de mémoire est pratiquement et dans quelle mesure il est vraiment actuellement présents dans la mémoire physique.

À la fin de chaque cliché est aussi un tableau de synthèse avec les sommes de différents types de mémoire. Ce tableau ressemble à ceci pour Firefox en ce moment sur mon système:

REGION TYPE             [ VIRTUAL/RESIDENT]
===========             [ =======/========]
ATS (font support)      [   33.8M/   2496K]
CG backing stores       [   5588K/   5460K]
CG image                [     20K/     20K]
CG raster data          [    576K/    576K]
CG shared images        [   2572K/   2404K]
Carbon                  [   1516K/   1516K]
CoreGraphics            [      8K/      8K]
IOKit                   [  256.0M/      0K]
MALLOC                  [  256.9M/  247.2M]
Memory tag=240          [      4K/      4K]
Memory tag=242          [     12K/     12K]
Memory tag=243          [      8K/      8K]
Memory tag=249          [    156K/     76K]
STACK GUARD             [  101.2M/   9908K]
Stack                   [   14.0M/    248K]
VM_ALLOCATE             [   25.9M/   25.6M]
__DATA                  [   6752K/   3808K]
__DATA/__OBJC           [     28K/     28K]
__IMAGE                 [   1240K/    112K]
__IMPORT                [    104K/    104K]
__LINKEDIT              [   30.7M/   3184K]
__OBJC                  [   1388K/   1336K]
__OBJC/__DATA           [     72K/     72K]
__PAGEZERO              [      4K/      0K]
__TEXT                  [  108.6M/   63.5M]
__UNICODE               [    536K/    512K]
mapped file             [  118.8M/   50.8M]
shared memory           [    300K/    276K]
shared pmap             [   6396K/   3120K]

Qu'est-ce que nous disent? E. g. Firefox binaire et tous de la bibliothèque des charges 108 MO de données ensemble dans leur __les sections de TEXTE, mais actuellement seulement 63 MO de ceux qui sont actuellement résident en mémoire. La prise en charge des polices (ATS) les besoins de 33 MO, mais seulement environ 2,5 MO sont vraiment dans la mémoire. Il utilise un peu plus de 5 MO, CG de la sauvegarde des magasins, CG = Graphiques de Base, ceux qui sont les plus susceptibles contenu de la fenêtre, les boutons, les images et autres données qui est mis en cache pour un dessin rapide. Il a demandé à 256 MO via malloc appels et actuellement 247 MO sont vraiment dans mappés à des pages de mémoire. Il dispose de 14 MO d'espace réservé pour les piles, mais seulement 248 KO d'espace de pile est vraiment en cours d'utilisation dès maintenant.

vmmap a aussi un bon résumé au-dessus de la table

ReadOnly portion of Libraries: Total=139.3M resident=66.6M(48%) swapped_out_or_unallocated=72.7M(52%)
Writable regions: Total=595.4M written=201.8M(34%) resident=283.1M(48%) swapped_out=0K(0%) unallocated=312.3M(52%)

Et cela montre un aspect intéressant de l'OS X: Pour mémoire en lecture seule, il ne joue aucun rôle, s'il est échangé ou tout simplement non alloué; il n'est qu'résident et non résident. Pour l'écriture de la mémoire cela fait une différence (dans mon cas, 52% de toutes les demandes de mémoire n'a jamais été utilisé et est non alloué, 0% de mémoire a été transférée sur le disque)

11voto

Justin L. Points 1427

Sous Linux, vous souhaiterez peut-être les nombres PSS (taille de jeu proportionnelle) dans / proc / self / smaps. Le PSS d'un mappage est son RSS divisé par le nombre de processus qui utilisent ce mappage.

7voto

alex Points 3964

Tu ne peux vraiment pas.

Je veux dire, la mémoire partagée entre les processus ... allez-vous la compter ou non. Si vous ne le comptez pas, vous vous trompez; la somme de l'utilisation de la mémoire de tous les processus ne sera pas l'utilisation totale de la mémoire. Si vous le comptez, vous allez le compter deux fois - la somme ne sera pas correcte.

Moi, je suis content de RSS. Et sachant que vous ne pouvez pas vraiment vous y fier complètement ...

7voto

Chris Points 2432

Top sait comment faire cela. Il montre VIRT, RES et SHR par défaut sur Linux Debian. VIRT = SWAP + RES. RES = CODE + DONNÉES. SHR est la mémoire qui peut être partagé avec un autre processus (bibliothèque partagée ou autre mémoire.)

Aussi, "sale" de la mémoire est simplement RES de la mémoire qui a été utilisée, et/ou n'a pas été échangés.

Il peut être difficile de le dire, mais la meilleure façon de le comprendre est de regarder d'un système qui n'est pas de permutation. Ensuite, RES - SHR est le processus exclusif de la mémoire. Cependant, ce n'est pas une bonne façon de le regarder, parce que vous ne savez pas que la mémoire de SHR est utilisé par un autre processus. Il peut représenter non écrite objet partagé les pages qui ne sont utilisées par le processus.

6voto

abc Points 2888

Vous pouvez obtenir des flux RSS propres et privés à partir de / proc / pid / smaps

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