13 votes

Changements de contexte non volontaires : Comment les prévenir ?

J'ai une petite application que je suis en train d'exécuter et je voulais vérifier s'il n'y avait pas de fuites de mémoire dans cette application :

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");
    }
}

Lorsque j'ai lancé l'application, j'ai cat'ed /proc//status pour voir si la mémoire augmente. La sortie est la suivante après environ 2 minutes d'exécution :

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 n'a changé, sauf la dernière, ce qui signifie qu'il n'y a pas de fuite de mémoire ?

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

J'ai regardé d'autres applications pour comparer le nombre d'interrupteurs non-volontaires dont elles disposent :

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

J'ai fait des recherches sur Internet et j'ai trouvé quelques trucs, mais c'est trop technique pour que je comprenne. Ce que j'en ai retenu, c'est que cela se produit lorsque l'application change de processeur ou quelque chose comme ça ? (J'ai un processeur Amd à 6 cœurs).

Comment puis-je empêcher mon application de faire cela et dans quelle mesure cela peut-il constituer un problème lors de l'exécution de l'application ?

Merci d'avance, Robin.

21voto

Sylvain Defresne Points 15231

Le 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.

Le changement de contexte non volontaire se produit lorsque votre application a utilisé toutes les tranches de temps que l'ordonnanceur lui a attribuées (le noyau essaie de faire croire que chaque application a tout l'ordinateur pour elle, et peut utiliser autant de CPU qu'elle veut, mais doit passer de l'une à l'autre pour que l'utilisateur ait l'illusion qu'elles fonctionnent toutes en parallèle).

Dans votre cas, puisque vous ouvrez, fermez et lisez le même fichier, il reste probablement dans le cache virtuel du système de fichiers pendant toute l'exécution du processus, et votre programme est préempté par le noyau car il ne bloque pas (à cause des caches du système ou des bibliothèques). D'autre part, Firefox, Gdm et Netbeans attendent principalement des entrées de l'utilisateur ou du réseau, et ne doivent pas être préemptés par le noyau.

Ces commutations de contexte ne sont pas nuisibles. Au contraire, ils permettent à votre processeur d'être utilisé de manière équitable par toutes les applications même si 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, tel que Valgrind .

3voto

Steve Townsend Points 36948

Pour compléter l'information de @Sylvain, il y a un bon article de fond sur la programmation de Linux ici : "Inside the Linux scheduler" (developerWorks, juin 2006) .

1voto

gravitron Points 1680

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 (utilisation de mémoire non initialisée, des tonnes d'autres problèmes). Je l'utilise presque tous les jours.

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