2010-12-13 52 views
11


J'ai une petite application que je courais en ce moment et je voulais vérifier si j'ai des fuites de mémoire dans ce si je mets dans ce morceau de code:Changements de contexte non volontaires: Comment puis-je les empêcher?

for (unsigned int i = 0; i<10000; i++) { 
    for (unsigned int j = 0; j<10000; j++) { 
     std::ifstream &a = s->fhandle->open("test"); 
     char temp[30]; 
     a.getline(temp, 30); 
     s->fhandle->close("test"); 
    } 
} 

Quand je courais l'application i cat'ed/proc // status pour voir si la mémoire augmente. La sortie est le suivant après environ 2 minutes d'autonomie:

Name: origin-test 
State: R (running) 
Tgid: 7267 
Pid: 7267 
PPid: 6619 
TracerPid: 0 
Uid: 1000 1000 1000 1000 
Gid: 1000 1000 1000 1000 
FDSize: 256 
Groups: 4 20 24 46 110 111 119 122 1000 
VmPeak: 183848 kB 
VmSize: 118308 kB 
VmLck:   0 kB 
VmHWM:  5116 kB 
VmRSS:  5116 kB 
VmData:  9560 kB 
VmStk:  136 kB 
VmExe:  28 kB 
VmLib:  11496 kB 
VmPTE:  240 kB 
VmSwap:  0 kB 
Threads: 2 
SigQ: 0/16382 
SigPnd: 0000000000000000 
ShdPnd: 0000000000000000 
SigBlk: 0000000000000000 
SigIgn: 0000000000002004 
SigCgt: 00000001800044c2 
CapInh: 0000000000000000 
CapPrm: 0000000000000000 
CapEff: 0000000000000000 
CapBnd: ffffffffffffffff 
Cpus_allowed: 3f 
Cpus_allowed_list: 0-5 
Mems_allowed: 00000000,00000001 
Mems_allowed_list: 0 
voluntary_ctxt_switches: 120 
nonvoluntary_ctxt_switches: 26475 

Aucune des valeurs a changé sauf le dernier, donc ne la moyenne, il n'y a pas de fuites de mémoire?

Mais ce qui est plus important et ce que je voudrais savoir est, s'il est mauvais que la dernière valeur augmente rapidement (environ 26475 commutateurs en environ 2 minutes!).

J'ai regardé d'autres applications pour comparer la quantité de commutateurs non volunary ils ont:

  1. Firefox: environ 200
  2. Gdm: 2
  3. Netbeans: 19

Ensuite, J'ai fait des recherches sur google et découvert des choses mais c'est technique à comprendre. Ce que j'ai obtenu de cela est que cela se produit lorsque l'application change le processeur ou quelque chose? (J'ai un processeur Amd 6-core btw).

Comment puis-je empêcher mon application de le faire et dans quelle mesure cela peut-il être un problème lors de l'exécution de l'application? Merci d'avance, Robin.

+1

Puisque vous êtes probablement sur linux, pourquoi ne pas utiliser valgrind pour vous aider à trouver une fuite de mémoire possible? – Palmik

+0

Je ne comprends pas pourquoi vous pensez que le code pourrait vous aider à vérifier les fuites de mémoire. – Ferruccio

+0

Eh bien, je suppose que cela pourrait l'aider à trouver une fuite de mémoire dans le code qui alloue/détruit le flux de fichier d'entrée. –

Répondre

19

Un changement de contexte volontaire se produit lorsque votre application est bloquée dans un appel système et que le noyau décide de donner sa tranche de temps à un autre processus.

Un changement de contexte non volontaire se produit lorsque votre application utilise tous les horaires que le planificateur lui a attribués (le noyau essaie de prétendre que chaque application possède tout l'ordinateur et peut utiliser autant de CPU qu'il le souhaite, mais a passer de l'un à l'autre pour que l'utilisateur ait l'illusion qu'ils courent tous en parallèle). Dans votre cas, puisque vous ouvrez, fermez et lisez depuis le même fichier, il reste probablement dans le cache du système de fichiers virtuel pendant toute l'exécution du processus, et votre programme est préempté par le noyau comme il ne bloque pas (soit à cause des caches système ou bibliothèque). D'autre part, Firefox, Gdm et Netbeans attendent la plupart du temps l'entrée de l'utilisateur ou du réseau, et ne doivent pas être préemptés par le noyau.

Ces commutateurs de contexte ne sont pas dangereux. Au contraire, cela permet à votre processeur d'être utilisé correctement par toutes les applications, même lorsque l'une d'entre elles attend une ressource.≈

Et BTW, pour détecter les fuites de mémoire, une meilleure solution serait d'utiliser un outil dédié à cela, comme valgrind.

+6

En d'autres termes, ce n'est pas un problème, c'est comme ça que fonctionne Unix. –

+3

Plus qu'unix, chaque système d'exploitation multitâche préemptif (c'est-à-dire, presque tous les systèmes d'exploitation d'usage courant). –

+0

Non volontaire? Ou voulez-vous dire volontaire? Si je comprends bien, lorsque vous appelez le système d'exploitation, vous lui cédez le contrôle, donc s'il décide de changer de contexte, il est "volontaire". Et quand votre application consomme juste beaucoup de CPU (comme dans ces boucles), le système d'exploitation peut choisir de suspendre de force l'exécution d'une application et de changer de contexte "de façon non volontaire". Ai-je tort? –

1

Pour rechercher une fuite de mémoire, il est préférable d'installer et d'utiliser valgrind, http://www.valgrind.org/. Il identifiera les fuites de mémoire dans le tas et les conditions d'erreur de mémoire (en utilisant la mémoire non initialisée, des tonnes d'autres problèmes). Je l'utilise presque tous les jours.