Tuning Solaris: Memoria

Uno de los elementos del sistema que afectan directamente al rendimiento del sistema son las operaciones de acceso a memoria, ya sea, memoria principal, caches, memoria secundaria, etc. En casos en los que la degradación del rendimiento sea apreciable, una de las principales causas, es la forma en la que las aplicaciones acceden a la memoria y como nuestro sistema está configurado para responder a dichas peticiones. Tal como hemos hecho con otros elementos del sistemas, el análisis del rendimiento de las operaciones sobre la memoria, lo vamos a comenzar desde un punto de vista global, el cual iremos concretando hacia los distintos elementos que conforman la memoria de nuestro sistema.

El sistema de memoria es un conjunto de elementos, que agrupan distintos tipos de memoria, a grandes rasgos, podemos decir que nuestro sistema dispone de tres tipos de memoria, memoria cache, memoria principal y memoria secundaria.
Memoria cache, es la memoria más rápida de la que se dispone en el sistema, normalmente está integrada dentro de los procesadores lo que obliga a que esta memoria sea de pequeño tamaño. Nosotros podemos ver el rendimiento de estas memorias y aunque no disponemos de parámetros para modificarlas, ya que son elementos HW, si disponemos de parámetros en el SO para modificar el tipo de acceso a estas memorias.
Memoria principal, se considera memoria principal, la memoria de acceso aleatorio, que está conectada a los procesadores, pero que no forman parte de ellos, es memoria volátil y se utiliza para almacenar los datos con los que está trabajando el procesador, es la memoria conocida comúnmente como RAM.
Memoria secundaria, es memoria mucho más lenta que la memoria principal, porque está construida con elementos mecánicos, como los discos duros, está memoria es no-volátil y se utiliza para almacenar de forma permanente, datos de las aplicaciones, el código de las aplicaciones, etc. El acceso a memoria secundaria es, hoy día, uno de los grandes cuellos de botella de las aplicaciones y los SO, por la gran cantidad de datos con los que trabajan las aplicaciones, así como el tamaño de las misma, nos obliga a tener que almacenar mucha información necesaria para la ejecución de las aplicaciones en disco. El área de intercambio de los SO, normalmente se almacena en este tipo de memoria.
En el artículo Solaris: Buceando en el Kernel con mdb (III) se describen algunos
de los elementos que se utilizan para organizar la memoria, tales como páginas, segmentos, etc. Entendemos que se tienen unos conocimientos mínimos sobre la forma en la que se organizan los distintos elementos de la memoria, para no repetir lo hablado en el artículo anterior.
Al igual que hicimos con el uso de CPU en el artículo Rendimiento/Tuning Solaris: Procesos y procesadores, vamos a comenzar intentando desmontar, en la medida de lo posible, el axioma:
“Poca memoria libre en el sistema, está directamente relacionada con un problema en el rendimiento”
Los sistemas Unix y en concreto los sistemas Solaris, tienden a utilizar toda la memoria disponible del sistema, por lo tanto, es normal que al consultar la cantidad de memoria libre en nuestro sistema, ésta esté bastante baja. El Kernel utilizará memoria libre para el sistema de Page Cache por ejemplo o para el área de SWAP, podemos asegurar que la cantidad de memoria libre en el sistema no es un parámetro fiable para detectar un problema en el rendimiento del mismo.
Puede que nuestro sistema no tenga mucha memoria libre y sin embargo funcione perfectamente o por el contrario, que tengamos mucha memoria libre, pero el rendimiento del sistema no es el deseado y que está lentitud, esté provocada por un problema en el acceso a memoria. Por lo tanto tenemos que tener claro, que una cosa es la cantidad de memoria libre del sistema y otra distinta es la forma en la que se está utilizando la memoria.
En nuestro estudio sobre el rendimiento en el uso de la memoria del sistema debemos centrarnos en los siguientes aspectos:
Que el tamaño de la memoria, tanto principal, como secundaria, sean los correctos para que el sistema no tenga que reducir su rendimiento. Como hemos dicho, los sistemas Solaris tienden a utilizar toda la memoria disponible en el sistema, por lo tanto, la cantidad de memoria libre no es un indicativo para conocer si nuestro sistema requiere más memoria. Existen otros indicadores en Solaris que nos ayudarán a predecir si el rendimiento de nuestro sistema aumentará si añadimos más memoria al sistema.
Poder detectar fugas de memoria en la aplicaciones. Cuando un programa reserva memoria, realiza una petición al SO para que se la facilite, una vez que la aplicación ha dejado de utilizar la memoria solicitada, debería liberarla o reutilizarla, bien, algunas aplicaciones, por culpa de bugs de programación, no liberan o reutilizan dicha memoria, sino que siguen solicitando más memoria al SO, el cual se la vuelve a facilitar, si esta circunstancia se repite muchas veces, el efecto que se produce, es que el sistema cada vez dispone de menos memoria libre, como si se estuviera perdiendo o fugando la memoria. Aunque la detección de las fugas de memoria debe realizarse durante el proceso de desarrollo, algunas veces esto no ocurre, quizás porque no se ha probado o bien porque durante las pruebas no se pudo reproducir una determinada situación, en este último caso, debemos detectar la fuga de memoria mientras la aplicación está corriendo en los sistema de producción. Detectar las fugas de memoria en los sistemas en producción, es una tarea que nos puede ahorrar muchos dolores de cabeza.
Que el sistema este optimizado para acceder de la forma más rápida a las distintas capas de memoria. Muchas veces se relaciona el acceso a la memoria con la velocidad de los buses, entre el procesador y los chips de memoria, y aunque por supuesto que la velocidad de los buses es un factor importante, es algo que depende de los fabricante. Cuando un proceso solicita un dato de memoria a un procesador, se producen una serie de operaciones que por si solas pueden ser ridículas, en cuanto a su tiempo de ejecución, pero que multiplicadas por miles, son operaciones que consumen un tiempo nada despreciable. Por ejemplo, que un dato que se solicita, esté en una página almacenada en disco, supone que se realicen varios accesos a memoria principal, esta operación es mucho más lenta que una operación de acceso a un dato que se encuentre almacenado en la memoria principal o en alguna de las caches.
Fallos de página
Cuando el procesador solicita un dato, mediante su dirección en memoria, se dará alguno de los cuatro casos que se describen abajo.
El dato se encuentra en una página de la memoria física y la dirección física de esta página está mapeada en la MMU, con lo que el dato es facilitado al procesador.
Que la página donde se encuentra el dato, no está mapeada actualmente con una página de la memoria física, esto obliga al SO a buscar la página en memoria secundaria y una vez encontrada, mapearla con una página de memoria física, este caso se conoce como major page fault. El que un sistema sufra muchos fallos de página de este tipo es grave, ya que el sistema pierde muchos ciclos de CPU en hacer que un dato esté disponible
la procesador.
Que la página que necesita el procesador se encuentre mapeada en la memoria física de la máquina, pero la MMU no la tiene mapeada en su cache, lo que provoca que se debe realizar la traducción entre direccionamiento física y direccionamiento virtual, este fallo se conoce como minor page fault.
Este cuarto caso no afecta tanto al acceso como al tipo de operación que se quiere realizar sobre la página, el problema está en que se intente realizar una escritura en una página que está marcada en la MMU como de solo lectura, en este caso la MMU genera una excepción que informa al SO que debe buscar una página libre, copiar el contenido de la página origen a la nueva página libre que se ha encontrado, mapear la nueva página y realizar la escritura que se solicito. Esta excepción generada por la MMU se conoce como copy on write fault.
De los tipos de fallos de páginas, el que afectará directamente al rendimiento del sistema será major page fault, que provocará varios accesos a memoria y por lo tanto el consumo de una serie de ciclos de CPU, si se producen muchos fallos de este tipo, el número de ciclos aumentará de forma que afecten al rendimiento, ya que el SO tendrá que realizar varias operaciones por cada acceso a memoria que produzca un fallo de este tipo.

vmstat
El comando vmstat nos devuelve una serie de estadísticas sobre distintos parámetros de memoria, esta herramienta nos puede ayudar a conocer qué está ocurriendo con la memoria del sistema, pero al igual que ocurría con el comando mpstat, no debemos mirar solo los datos típicos, debemos realizar un análisis algo más detallado de los distintos elementos que nos presenta el comando.

kthr memory page disk faults cpu
r b w swap free re mf pi po fr de sr s0 s1 s2 s3 in sy cs us sy id
0 0 0 19524272 4829696 274 1862 0 0 0 0 0 0 4 4 4 3050 49799 9984 22 13 65
0 0 0 19524488 4832584 678 1902 0 0 0 0 0 0 4 4 4 3104 33856 10656 24 11 65
0 0 0 19530296 4837064 63 65 0 0 0 0 0 0 4 4 4 3508 12118 11437 22 6 72
0 0 0 19530296 4837064 0 2 0 0 0 0 0 0 4 4 4 3237 11180 10919 21 5 74
0 0 0 19530296 4837072 268 1126 0 0 0 0 0 0 0 0 1 2973 29572 10315 20 6 74
3 0 0 19530296 4837072 240 685 0 0 0 0 0 0 0 0 1 2443 26349 9010 15 6 79
0 0 0 19530296 4837064 414 838 24 0 0 0 0 0 0 0 1 1737 9148 7642 19 5 76
0 0 0 19530296 4837096 63 63 0 0 0 0 0 0 0 0 1 2678 9529 9562 12 8 79
0 0 0 19530296 4837088 0 1 0 0 0 0 0 0 0 0 1 2754 9871 9980 11 2 86
0 0 0 19530296 4837088 0 0 0 0 0 0 0 0 0 0 1 3197 11096 10916 18 4 78
0 0 0 19530296 4837088 0 0 0 0 0 0 0 0 0 0 1 3153 11193 10797 16 5 80
2 0 0 19528072 4833872 1175 5494 0 0 0 0 0 0 0 0 1 2911 92948 9673 38 20 43
0 0 0 19530296 4837072 532 3289 0 0 0 0 0 0 1 1 2 3316 69628 10643 34 15 51
0 0 0 19530296 4837072 0 2 0 0 0 0 0 0 1 1 2 3579 12530 11880 19 7 75
0 0 0 19530296 4837096 241 678 0 16 16 0 0 0 1 1 2 2625 27055 9599 13 8 79
De la salida de vmstat nos interesan la columnas:
r b w que nos devuelven los proceso en la cola de ejecución, los procesos bloqueados y el número de procesos que están en la SWAP.
re page reclaims, cuando el Kernel necesita una página nueva, la buscará dentro de las páginas libres en la free list o en la lista de páginas cacheadas de la cache list, cuando el Kernel coge una página de la cache list se dice que se ha producido una page reclaim. Por lo tanto, esta columna nos indicará que el Kernel está solicitando nuevas páginas memoria.
mf Fallo de página menor, este tipo de fallos se producen cuando en procesador intenta acceder a una página que está mapeada en la memoria física de la máquina, pero la MMU no la tiene mapeada en su caché, lo que provoca que se tenga que mapear en dicha caches. Normalmente
un gran número fallos de este tipo indican un problema con la gestión de las caches TLB y TSB de la MMU.
pi po, page in y page out estas dos columnas nos informan de la transferencia que se está produciendo entre la memoria secundaria y la principal. Tener un número elevado de pi o po durante una periodo prolongado de tiempo, nos indica que existe un problema con la cantidad de memoria en el sistema, ya que el Kernel está gastando mucho tiempo en coger páginas de memoria principal y pasarlas al área de SWAP o a un fichero y viceversa.
fr esta columna nos informa sobre la cantidad de páginas que se están liberando.
sr scan rate, es el número de página escaneadas por el Page Scanner, el cual se encarga de buscar páginas a las cuales no se haya accedido en un determinado tiempo, una vez que el Page Scanner encuentra una página, su contenido se pasa a la memoria secundaria para liberarla. El tener unos valores por encima de 200 en esta columna nos indica un problema con la cantidad de memoria que necesita el sistema.
MDB
Como hemos podido ver en los artículos dedicados a Modular Debugger, éste nos puede ayudar a conocer qué está ocurriendo con la memoria de nuestro sistema. Uno de los comandos de mdb que nos facilita un resumen del uso de la memoria por parte de nuestro sistema es ::memstat.

(root@camtrunet)# mdb -k
Loading modules: [ unix krtld genunix specfs dtrace uppc pcplusmp scsi_vhci
ufs ip sctp arp usba uhci nca s1394 lofs zfs random audiosup md crypto
logindmux ptm sppp nfs ipc ]
> ::memstat
Page Summary Pages MB %Tot
------------ ---------------- ---------------- ----
Kernel 29170 113 23%
Anon 38713 151 30%
Exec and libs 15839 61 12%
Page cache 2745 10 2%
Free (cachelist) 20267 79 16%
Free (freelist) 22176 86 17%

Total 128910 503
Physical 128909 503
>
Con este comando podremos analizar qué elementos de nuestro sistema son los que que están consumiendo más memoria y si estos datos de consumo se corresponden con lo que nosotros esperamos. Es importante que vigilemos la cantidad de memoria asignada a páginas anónimas, nos puede ayudar a identificar un problema de fuga de memoria, o la cantidad de memoria asignada a páginas Exec and libs, que no dirá si el sistema tiene problemas con la cantidad de procesos que se están ejecutando.
pmap
Este comando nos devuelve como salida el mapa de memoria, el espacio de direcciones, de un determinado proceso, tiene una serie de parámetros, los cuales podemos consultar en el man. Al igual que hemos hecho con el comando ::memstat de MDB para toda la memoria del sistema, podemos utilizar pmap para vigilar el crecimiento de ciertos segmentos del espacio de direcciones de un procesos.

(root@camtrunet)# pmap -x 26089
26089: sh -c echo "Hola mundo"
Address Kbytes RSS Anon Locked Mode Mapped File
00010000 88 88 - - r-x-- sh
00036000 8 8 8 - rwx-- sh
00038000 16 16 16 - rwx-- [ heap ]
FF280000 688 688 - - r-x-- libc.so.1
FF33C000 32 32 32 - rwx-- libc.so.1
FF360000 8 8 8 - rwx-- [ anon ]
FF370000 24 24 - - r-x-- libgen.so.1
FF386000 8 8 8 - rwx-- libgen.so.1
FF390000 8 8 - - r-x-- libc_psr.so.1
FF39A000 8 8 8 - rwx-- libdl.so.1
FF3A0000 8 8 - - r--s- dev:273,0 ino:95059
FF3B0000 184 184 - - r-x-- ld.so.1
FF3EE000 8 8 8 - rwx-- ld.so.1
FF3F0000 8 8 8 - rwx-- ld.so.1
FFBFE000 8 8 8 - rw--- [ stack ]
-------- ------- ------- ------- -------
total Kb 1104 1104 104 -
(root@camtrunet)#
Con el parámetro -x, el comando pmap devolverá un columna con la información sobre la memoria Anónima que se está utilizando en cada segmento, esto nos ayudará en la identificación de una posible fuga de memoria. Hay que vigilar los segmentos heap y stack.

Comentarios

Entradas populares de este blog

Comandos Solaris

MikroTik QoS Script generator

Comando para eliminar saltos de linea en fichero o archivo desde consola Linux