Libération de la mémoire allouée sous Solaris / Linux

J’ai écrit un petit programme et l’ai compilé sous la plateforme Solaris / Linux pour mesurer les performances de l’application de ce code à mon application.

Le programme est écrit de cette 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 cela, j’ai alloué 1,5 Go de mémoire à l’aide d’un appel système malloc , puis j’ai utilisé un memcpy système memcpy pour copier 1,5 Go de contenu dans la zone mémoire allouée. Ensuite, j’ai libéré la mémoire allouée.

Après avoir libéré, j’ai utilisé à nouveau l’appel système sbrk(0) pour afficher la taille du segment de mémoire.

C’est là que je suis un peu confus. Sous Solaris, même si j’ai libéré la mémoire allouée (près de 1,5 Go), la taille de segment du processus est énorme. Mais je lance la même application sous Linux, après avoir libéré, j’ai constaté que la taille de segment de mémoire du processus est égale à la taille de la mémoire de segment de mémoire avant l’allocation de 1,5 Go.

Je sais que Solaris ne libère pas immédiatement la mémoire, mais je ne sais pas comment ajuster le kernel 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?

J’ai eu la réponse à la question que j’ai posée.

Allocateurs de mémoire d’application:

Les développeurs C et C ++ doivent gérer manuellement l’allocation de mémoire et la mémoire libre. L’allocateur de mémoire par défaut se trouve 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 restitué au système. La mémoire est renvoyée au système uniquement à la fin de l’application. 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 de l’application rest généralement stable, car la mémoire libérée peut être réutilisée. Si ce n’est pas le cas, l’application perd probablement de la mémoire, c’est-à-dire que la mémoire allouée est utilisée mais qu’elle n’est jamais libérée lorsqu’elle n’est plus utilisée et que le pointeur sur la mémoire allouée n’est pas suivi par l’application, c’est-à-dire perdu.

L’allocateur de mémoire par défaut dans libc n’est pas adapté aux applications multithreads lorsqu’une opération malloc ou free simultanée est fréquente, en particulier pour les applications C ++ multithreads. En effet, la création et la destruction d’objects C ++ font partie du style de développement d’applications C ++. Lorsque l’allocateur libc par défaut est utilisé, le segment de mémoire est protégé par un verrou de segment unique, ce qui l’empêche de devenir évolutif pour les applications multithreads en raison de conflits de locking importants lors d’opérations malloc ou free. Il est facile de détecter ce problème avec les outils Solaris, comme suit.

Premièrement, 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 .... 

Cela montre que l’application passe environ 35% de son temps à attendre les verrous.

Ensuite, à l’aide de l’outil plockstat (1M), recherchez ce qui verrouille l’application attendue. Par exemple, tracez l’application pendant 5 secondes à l’aide de l’ID de processus 14052, puis filtrez la sortie à l’aide de l’utilitaire c ++ filt pour démêler les noms de symbole 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 ...... 

D’après ce qui précède, vous pouvez constater que libc_malloc_lock, verrou de segment de mémoire, est fortement contesté et constitue une cause probable du problème de mise à l’échelle. La solution à ce problème de mise à l’échelle de l’allocateur libc consiste à utiliser un allocateur de mémoire amélioré, comme la bibliothèque libumem.

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

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