2009-12-11 3 views
4

Je tente de mesurer l'utilisation de la mémoire d'un processus (un programme java) sur linux et ont deux questions à ce sujet:utilisation de la mémoire de mesure d'un processus sur Linux

  1. J'ai essayé d'utiliser le script ps_mem.py (somme des valeurs de/proc/$ PID/smaps) et le pic de l'utilisation totale de la mémoire était d'environ 135 Mo (mémoire privée et partagée). La quantité de mémoire partagée est inférieure à 1 Mo. Essayer d'utiliser Valgrind avec l'outil massif valgrind --tool=massif --trace-children=yes --stacks=yes java myProgram donne environ 10 Mo au maximum de l'utilisation de la mémoire.
    Maintenant, si je comprends bien, heap est où les variables de mon programme sont stockées, cela signifie-t-il que la différence entre les deux méthodes est l'espace pris par le code lui-même (y compris le jvm)? Le même programme utilise-t-il une quantité différente de mémoire sur des machines différentes si elles ont une quantité différente de RAM ou/et utilisent des processeurs différents (ARM ou x86)?

Répondre

3
  1. Dépend.
    • La plupart des mappages de mémoire partagée dans smaps sont directement gérés par des bibliothèques/binaires sur le disque. Même si l'empreinte de ces éléments est importante, il est moins important que le système puisse les supprimer à tout moment et les recharger à partir du disque si nécessaire.
    • Tout ce qui est sale ou privé appartient exclusivement au processus en cours (bien, arbre de processus si votre programme forks sans execs). Ceci est plus important car le système doit les enregistrer pour échanger si ces pages doivent être déplacées.
    • Quel massif mesure est probablement en corrélation avec ce dernier. Cependant, la mémoire prise par la JVM elle-même (sans votre programme) est dans les deux.
  2. Oui. Java ou une bibliothèque qu'il utilise peut ajuster son modèle de mémoire en fonction de la taille de la RAM disponible.Sur une architecture différente, vous utilisez des binaires complètement différents, qui peuvent être plus grands ou plus petits ou disposés différemment ou en utilisant des stratégies différentes pour la gestion JIT et la gestion de la mémoire.
1

Pour la valeur 1, la mémoire partagée est de la mémoire (potentiellement) utilisée par plusieurs processus. C'est essentiellement si vous exécutez le même fichier binaire dans plusieurs processus ou si des processus différents utilisent une bibliothèque partagée. Le tas est où la mémoire allouée est stockée (lorsque vous utilisez new en Java). Puisque Java a sa VM, elle alloue beaucoup de mémoire au niveau du processus que vous ne voyez pas dans votre code java. Je pense que oui, la majorité de ces 135 Mo provient du code/des données JVM lui-même. Cependant, il y a aussi la mémoire occupée par la pile (lorsque vous faites un appel de fonction et que vous avez des variables locales). Pour le n ° 2, une quantité différente de RAM n'affecterait pas la quantité de "mémoire" utilisée lorsque nous laissons la mémoire égale à RAM + espace d'échange. Cependant, différents processeurs (surtout si nous parlons de 32 bits par rapport à 64 bits) peuvent utiliser une quantité de mémoire différente. En outre, la façon dont un processus est compilé peut modifier la quantité de mémoire utilisée car vous pouvez demander à un compilateur d'optimiser l'empreinte mémoire sur la vitesse, ainsi que de désactiver complètement ou partiellement toute l'optimisation.

0

Vous voudrez peut-être jeter un oeil à JConsole. Les choses peuvent être difficiles en fonction du but de votre mesure. Si vous voulez connaître l'utilisation de la mémoire de votre programme Java, les outils qui mesurent l'utilisation de la mémoire d'un processus seront inexacts car ils montreront la mémoire utilisée par la JVM ainsi que votre programme. En ce qui concerne l'outil massif, sachez que certaines parties de la JVM seront stockées sur la pile, et que le code java lui-même pourrait être sur le tas (puisqu'il s'agit d'une variable de la JVM), je ne connais pas assez à propos de la JVM à dire.

3

Il existe une question similaire à ceci et répondant à la même question ici pour informer les gens de la façon dont linux proc stat vm info n'est actuellement pas précise.
Valgrind peut afficher des informations détaillées, mais il ralentit considérablement l'application cible, et la plupart du temps, il modifie le comportement de l'application.

Je suppose que tout le monde veut savoir WRT "utilisation de la mémoire" est la suivante ...
Dans Linux, la quantité de mémoire physique d'un processus peut utiliser peut être divisée en catégories suivantes.

  • Ma anonyme cartographié la mémoire
    • .p privé
      • .d sale == malloc/tas mmapped et pile alloué et de la mémoire écrit
      • .c propre == malloc/tas mmapped et empiler la mémoire une fois allouée, écrite, puis libérée, mais pas encore récupérée
    • .s partagé
      • .d sale == il devrait y avoir aucun
      • .c propre == il devrait y avoir aucun
  • Mn appelée mémoire mappée
    • .p privé
      • .d sale == fichier mmapped mémoire écrite privée
      • .c propre == programme cartographié/texte bibliothèque privée mappée
    • .s partagé
      • .d sale fichier == mmapped écrit la mémoire partagée
      • .c == propre texte mis en correspondance bibliothèque partagée mappée

Je préférerais obtenir les chiffres comme suit pour obtenir les chiffres réels moins Ove rhead.
Vous devez les additionner afin de diviser ce que PS montre comme RSS et obtenir des nombres plus précis pour ne pas confondre.
/proc/(pid)/status essaie d'afficher ces nombres, mais ils échouent. Donc au lieu d'essayer d'étiqueter [anon], [pile], correctement à chaque mapping, mon souhait est que les gens du noyau Linux vont mettre à jour le code d'entrée proc pour additionner et montrer ces Mapd, Mapc, Mnpd, .... Nombres.
Les gens de linux embarqués seront vraiment heureux à mon humble avis.

M.a.p.d:

awk '/^[0-9a-f]/{if ($6=="") {anon=1}else{anon=0}} /Private_Dirty/{if(anon) {asum+=$2}else{nasum+=$2}} END{printf "sum=%d\n",asum}' /proc/<pid>/smaps 

M.a.p.c:

awk '/^[0-9a-f]/{if ($6=="") {anon=1}else{anon=0}} /Private_Clean/{if(anon) {asum+=$2}else{nasum+=$2}} END{printf "sum=%d\n",asum}' /proc/<pid>/smaps 

M.n.p.d: ... et ainsi de suite

Questions connexes