2010-06-01 7 views
4

J'ai écrit un petit programme et l'ai compilé sous plate-forme Solaris/Linux pour mesurer les performances de l'application de ce code à mon application.Libération de la mémoire allouée sous Solaris/Linux

Le programme est écrit de telle manière, en utilisant initialement un appel système sbrk(0), j'ai pris l'adresse de base de la région de tas. Après que j'ai alloué 1,5 Go de mémoire en utilisant un appel système malloc, Puis j'ai utilisé un appel système memcpy pour copier 1,5 Go de contenu dans la zone de mémoire allouée. Ensuite, j'ai libéré la mémoire allouée. Après la libération, j'ai de nouveau utilisé l'appel système sbrk(0) pour afficher la taille du segment.

C'est là que je suis un peu confus. Dans Solaris, même si j'ai libéré la mémoire allouée (près de 1,5 Go), la taille du tas du processus est énorme. Mais j'ai exécuté la même application sous Linux, après avoir libéré, j'ai trouvé que la taille du tas du processus est égale à la taille de la mémoire de tas avant allocation de 1,5 Go. Je sais que Solaris ne libère pas la mémoire immédiatement, mais je ne sais pas comment régler le noyau Solaris pour libérer immédiatement la mémoire après l'appel système free(). Pourquoi n'ai-je pas le même problème sous Linux?

Répondre

3

J'ai obtenu la réponse à la question que j'ai posée.

Mémoire application Allocators:

C et les développeurs C doit de gérer manuellement l'allocation de mémoire et de la mémoire libre. L'allocateur de mémoire par défaut est dans la bibliothèque libc.

Libc Notez qu'après l'exécution de free(), l'espace libéré est rendu disponible pour une allocation supplémentaire par l'application et n'est pas renvoyé au système. La mémoire est renvoyée au système uniquement lorsque l'application se termine. C'est pourquoi la taille du processus de l'application ne diminue généralement jamais. Mais pour une application de longue durée, la taille du processus d'application reste généralement dans un état stable car la mémoire libérée peut être réutilisée. Si ce n'est pas le cas, l'application perd de la mémoire, c'est-à-dire que la mémoire allouée est utilisée mais jamais libérée lorsqu'elle n'est plus utilisée et que le pointeur vers la mémoire allouée n'est pas suivi par l'application. L'allocateur de mémoire par défaut dans libc n'est pas bon pour les applications multithread lorsqu'une opération simultanée malloc ou free se produit fréquemment, en particulier pour les applications C++ multithread. En effet, la création et la destruction d'objets C++ font partie du style de développement d'applications C++. Lorsque l'allocateur de libc par défaut est utilisé, le tas est protégé par un seul heap-lock, ce qui fait que l'allocateur par défaut n'est pas évolutif pour les applications multithread en raison de conflits de verrous importants lors des opérations malloc ou free. Il est facile de détecter ce problème avec les outils Solaris, comme suit. D'abord, utilisez prstat -mL -p pour voir si l'application passe beaucoup de temps sur les verrous; regardez la colonne LCK. Par exemple:

-bash-3.2# prstat -mL -p 14052 
    PID USERNAME USR SYS TRP TFL DFL LCK SLP LAT VCX ICX SCL SIG PROCESS/LWPID 
14052 root  0.6 0.7 0.0 0.0 0.0 35 0.0 64 245 13 841 0 test_vector_/721 
14052 root  1.0 0.0 0.0 0.0 0.0 35 0.0 64 287 5 731 0 test_vector_/941 
14052 root  1.0 0.0 0.0 0.0 0.0 35 0.0 64 298 3 680 0 test_vector_/181 
14052 root  1.0 0.1 0.0 0.0 0.0 35 0.0 64 298 3 1K 0 test_vector_/549 
.... 

Il montre que l'application passe environ 35% de son temps à attendre des verrous. Puis, à l'aide de l'outil plockstat (1M), recherchez les verrouillages attendus par l'application. Par exemple, tracez l'application pendant 5 secondes avec l'ID de processus 14052, puis filtrez la sortie avec l'utilitaire C++ filt pour démêler les noms de symboles C++. (L'utilitaire C++ filt est fourni avec le logiciel Sun Studio.) Le filtrage via C++ filt n'est pas nécessaire si l'application n'est pas une application C++.

-bash-3.2# plockstat -e 5 -p 14052 | c++filt 
Mutex block 
Count  nsec Lock       Caller 
------------------------------------------------------------------------------- 
9678 166540561 libc.so.1‘libc_malloc_lock libCrun.so.1‘void operator 
delete(void*)+0x26 

5530 197179848 libc.so.1‘libc_malloc_lock libCrun.so.1‘void*operator 
new(unsigned)+0x38 

...... 

De ce qui précède, vous pouvez voir que le libc_malloc_lock verrouillage du tas est fortement soutenu et est une cause probable de la question de la mise à l'échelle. La solution pour ce problème de mise à l'échelle de l'allocateur de libc est d'utiliser un allocateur de mémoire amélioré comme la librairie libumem.

Visitez aussi: http://developers.sun.com/solaris/articles/solaris_memory.html

Merci pour tous ceux qui ont essayé de répondre à ma question, Santhosh.

Questions connexes