Estoy ejecutando un servidor Perl con 10 subprocesos. Nunca se destruyen hasta que el programa se cierra, pero esto es algo que pretendo tener el mayor tiempo de actividad posible, por eso es un problema para mí. Los hilos manejan una tarea simple muchas veces. Cuando inicio el servidor y todos los hilos se inician, veo que tengo 288.30 MB gratis. Después de un par de iteraciones a través de cada hilo, informa 285.96 MB gratis. Eso no es tan malo ... quizás sea solo un espacio de pila asignado o algo durante esas iteraciones. ¡Pero después de 15 minutos, la memoria libre baja a 248.24 MB! ¿Qué pasó con mi memoria? Ahora, curiosamente, HACE meseta. Continúa consumiendo lentamente, pero no tan rápido como al principio. Pensé que tal vez era mi culpa, así que intenté verificar el alcance de todas mis variables e incluso definirlas todas al final del ciclo.Los subprocesos Perl consumen memoria lentamente
Imprimo el espacio libre después de CADA iteración de los hilos para que pueda ver cómo baja lentamente. Ahora lo que también es interesante es que no disminuye cada vez. A veces, la memoria libre se mantiene igual después de iterar.
estoy usando Perl 5.8.8 construida desde las fuentes en Linux 2.6
¿Alguien tiene alguna idea en absoluto, o incluso sugerencias sobre lo que puede ser la causa de esto? Estoy considerando actualizar mi Perl a una versión posterior para descartar una pérdida de memoria dentro del núcleo de Perl.
ACTUALIZACIÓN: ¿Podría ser un problema de tamaño de la pila de subprocesos? ¿Podría asignar más memoria para la pila de la que necesito? Cuando creo mis hilos, no cambio la configuración de los valores predeterminados. ¿Debería? El documento de hilos dice que el valor predeterminado generalmente es de 16 MB dependiendo del sistema. 16x10 hilos = 160MB -> que podría ser el culpable. ¿Pensamientos?
ACTUALIZACIÓN: Creé e instalé Perl 5.12.1 y reconstruí los módulos y todo. He estado ejecutando el script durante aproximadamente una hora y esto es lo que noté. El uso de la memoria es manejable ahora, pero no es ideal.
- Al principio justo después del desove mis hilos parecían ser un poco más bajos. Abajo de ~ 60-66MB asignado a mis 10 hilos a ~ 45-50MB.
- Después de algunas iteraciones, su uso aumentó en 3 MB en total (casi lo mismo que antes).
- Hasta este punto es lo que esperaba. Toda esa memoria por adelantado para el desove, y luego solo un poco por las variables que uso en mis hilos. Esta es la parte que no me gusta. ¡Después de correr durante aproximadamente 10 minutos, pierdo 65 MB adicionales! ¿Por qué hace esto? Si ya se ha repetido algunas veces bien con solo 3 MB, ¿por qué seguir asignando?
- Ha estado funcionando durante una hora y media en este punto y ya no usan 65MB adicionales, ¡son 84MB adicionales!
- Poco a poco lleva más memoria, pero lo extraño es que la cantidad de memoria libre no disminuye en cada iteración. Imprimo la memoria libre antes y después de cada iteración y permanecerá igual por un tiempo o desplazarme + - alrededor de cierto número por un tiempo y luego cambiar de 5 a 10 MB de repente. No puedo dejar que esto funcione más de uno, dos días como máximo porque comienza a acercarse al 80/90% de mi memoria disponible.
¿Hay alguna otra idea? ¿Alguna cosa que pueda probar? Ya estoy descifrando todas mis variables.
ACTUALIZACIÓN: Realmente quiero seguir compilando Perl con glibc como último recurso, ya que he encontrado algunos informes de que en algunos sabores de Linux se segfault.Así que desde la última vez que publiqué exploré aún más la posibilidad de ciclos en mis valores hash. Encontrar nada. Así que pasé los últimos días analizando mi subrutina y guardando en caché todo lo que se usa en otra iteración. Se recrean muchas cosas nuevas cada vez y Perl no las limpia todo, incluso si no lo explico explícitamente. Entonces, si no coopera, simplemente no lo destruiré. Veré si el almacenamiento en caché de mis objetos ayuda en absoluto. Publicará estadísticas de uso de memoria más tarde.
ACTUALIZACIÓN: Hm, muy extraño. Incluso después de guardar en caché mis datos para volver a usarlos más adelante, la memoria aumenta aproximadamente a la misma velocidad. Empieza más alto ahora porque estoy almacenando en caché, pero luego sigue aumentando a pesar de que usa principalmente mis objetos en caché. Eso es desconcertante. Supongo que es hora de probar Glibc ... o bien, esto es solo un inconveniente de elegir Perl y tendrá que vivir reiniciando el servidor cada dos días.
ACTUALIZACIÓN: Probado sin el almacenamiento en caché, no glibc, de nuevo. Funciona bien por un tiempo, unas pocas horas, luego comienza a crecer. Solo quería que veas un gráfico.
http://tinypic.com/r/311nc08/3
http://i32.tinypic.com/311nc08.jpg
UPDATE: He aquí un extracto de un registro de la documentación de la memoria libre antes y después de cada hilo por encima de aproximadamente un minuto. Tal vez esto puede ayudar a alguien a entender mejor el problema. Parece ser estable por un tiempo y de vez en cuando comerá más memoria como esta. ¡Aquí pierdo casi 40 MB!
[9:8:30, Fri Jul 23, 2010] [0] Memory usage at end thread 1: 253.812736MB (obj cache: 136)
[9:8:30, Fri Jul 23, 2010] [0] Memory usage at idle thread 1: 253.812736MB (obj cache: 136)
[9:8:34, Fri Jul 23, 2010] [204] Sending data to thread
[9:8:34, Fri Jul 23, 2010] [0] 3 - Creating a new obj
[9:8:34, Fri Jul 23, 2010] [206] Sending data to thread
[9:8:34, Fri Jul 23, 2010] [0] 4 - Creating a new obj
[9:8:35, Fri Jul 23, 2010] [0] Memory usage at end thread 3: 253.812736MB (obj cache: 136)
[9:8:35, Fri Jul 23, 2010] [0] Memory usage at idle thread 3: 253.812736MB (obj cache: 136)
[9:8:35, Fri Jul 23, 2010] [0] Memory usage at end thread 4: 253.812736MB (obj cache: 136)
[9:8:35, Fri Jul 23, 2010] [0] Memory usage at idle thread 4: 253.812736MB (obj cache: 136)
[9:8:41, Fri Jul 23, 2010] [225] Sending data to thread
[9:8:41, Fri Jul 23, 2010] [0] 2 - Creating a new obj
[9:8:42, Fri Jul 23, 2010] [0] Memory usage at end thread 2: 253.681664MB (obj cache: 136)
[9:8:42, Fri Jul 23, 2010] [0] Memory usage at idle thread 2: 253.681664MB (obj cache: 136)
[9:8:47, Fri Jul 23, 2010] [243] Sending data to thread
[9:8:47, Fri Jul 23, 2010] [0] 1 - Creating a new obj
[9:8:48, Fri Jul 23, 2010] [0] Memory usage at end thread 1: 253.935616MB (obj cache: 136)
[9:8:48, Fri Jul 23, 2010] [0] Memory usage at idle thread 1: 253.935616MB (obj cache: 136)
[9:9:1, Fri Jul 23, 2010] [277] Sending data to thread
[9:9:1, Fri Jul 23, 2010] [0] 3 - Creating a new obj
[9:9:2, Fri Jul 23, 2010] [280] Sending data to thread
[9:9:2, Fri Jul 23, 2010] [0] 4 - Creating a new obj
[9:9:2, Fri Jul 23, 2010] [0] Memory usage at end thread 3: 253.935616MB (obj cache: 136)
[9:9:2, Fri Jul 23, 2010] [0] Memory usage at idle thread 3: 253.935616MB (obj cache: 136)
[9:9:3, Fri Jul 23, 2010] [283] Sending data to thread
[9:9:3, Fri Jul 23, 2010] [0] 2 - Creating a new obj
[9:9:4, Fri Jul 23, 2010] [284] Sending data to thread
[9:9:4, Fri Jul 23, 2010] [0] 1 - Creating a new obj
[9:9:4, Fri Jul 23, 2010] [0] Memory usage at end thread 2: 253.935616MB (obj cache: 136)
[9:9:4, Fri Jul 23, 2010] [0] Memory usage at idle thread 2: 253.935616MB (obj cache: 136)
[9:9:5, Fri Jul 23, 2010] [287] Sending data to thread
[9:9:5, Fri Jul 23, 2010] [0] 3 - Creating a new obj
[9:9:5, Fri Jul 23, 2010] [0] Memory usage at end thread 4: 253.93152MB (obj cache: 136)
[9:9:5, Fri Jul 23, 2010] [0] Memory usage at idle thread 4: 253.93152MB (obj cache: 136)
[9:9:6, Fri Jul 23, 2010] [290] Sending data to thread
[9:9:6, Fri Jul 23, 2010] [0] 2 - Creating a new obj
[9:9:7, Fri Jul 23, 2010] [0] Memory usage at end thread 3: 253.804544MB (obj cache: 136)
[9:9:7, Fri Jul 23, 2010] [0] Memory usage at idle thread 3: 253.804544MB (obj cache: 136)
[9:9:7, Fri Jul 23, 2010] [0] Memory usage at end thread 1: 253.804544MB (obj cache: 136)
[9:9:7, Fri Jul 23, 2010] [0] Memory usage at idle thread 1: 253.804544MB (obj cache: 136)
[9:9:9, Fri Jul 23, 2010] [0] 4 - Creating a new obj
[9:9:9, Fri Jul 23, 2010] [301] Sending data to thread
[9:9:9, Fri Jul 23, 2010] [0] 3 - Creating a new obj
[9:9:9, Fri Jul 23, 2010] [302] Sending data to thread
[9:9:9, Fri Jul 23, 2010] [0] 1 - Creating a new obj
[9:9:10, Fri Jul 23, 2010] [0] 3 - Creating a new obj
[9:9:11, Fri Jul 23, 2010] [0] 3 - Creating a new obj
[9:9:11, Fri Jul 23, 2010] [0] Memory usage at end thread 4: 253.93152MB (obj cache: 136)
[9:9:11, Fri Jul 23, 2010] [0] Memory usage at idle thread 4: 253.93152MB (obj cache: 136)
[9:9:12, Fri Jul 23, 2010] [308] Sending data to thread
[9:9:12, Fri Jul 23, 2010] [0] 4 - Creating a new obj
[9:9:13, Fri Jul 23, 2010] [0] Memory usage at end thread 1: 253.804544MB (obj cache: 136)
[9:9:13, Fri Jul 23, 2010] [0] Memory usage at idle thread 1: 253.804544MB (obj cache: 136)
[9:9:14, Fri Jul 23, 2010] [0] Memory usage at end thread 4: 253.804544MB (obj cache: 136)
[9:9:14, Fri Jul 23, 2010] [0] Memory usage at idle thread 4: 253.804544MB (obj cache: 136)
[9:9:14, Fri Jul 23, 2010] [0] Memory usage at end thread 3: 253.93152MB (obj cache: 136)
[9:9:14, Fri Jul 23, 2010] [0] Memory usage at idle thread 3: 253.93152MB (obj cache: 136)
[9:9:15, Fri Jul 23, 2010] [313] Sending data to thread
[9:9:15, Fri Jul 23, 2010] [0] 1 - Creating a new obj
[9:9:16, Fri Jul 23, 2010] [0] Memory usage at end thread 2: 214.482944MB (obj cache: 136)
[9:9:16, Fri Jul 23, 2010] [0] Memory usage at idle thread 2: 214.482944MB (obj cache: 136)
[9:9:16, Fri Jul 23, 2010] [315] Sending data to thread
[9:9:16, Fri Jul 23, 2010] [0] 4 - Creating a new obj
[9:9:17, Fri Jul 23, 2010] [0] Memory usage at end thread 1: 214.355968MB (obj cache: 136)
[9:9:17, Fri Jul 23, 2010] [0] Memory usage at idle thread 1: 214.355968MB (obj cache: 136)
[9:9:18, Fri Jul 23, 2010] [316] Sending data to thread
[9:9:18, Fri Jul 23, 2010] [0] 3 - Creating a new obj
[9:9:18, Fri Jul 23, 2010] [317] Sending data to thread
[9:9:18, Fri Jul 23, 2010] [0] 2 - Creating a new obj
[9:9:18, Fri Jul 23, 2010] [318] Sending data to thread
[9:9:18, Fri Jul 23, 2010] [0] 1 - Creating a new obj
[9:9:19, Fri Jul 23, 2010] [0] Memory usage at end thread 4: 214.355968MB (obj cache: 136)
[9:9:19, Fri Jul 23, 2010] [0] Memory usage at idle thread 4: 214.355968MB (obj cache: 136)
[9:9:19, Fri Jul 23, 2010] [0] Memory usage at end thread 1: 214.355968MB (obj cache: 136)
[9:9:19, Fri Jul 23, 2010] [0] Memory usage at idle thread 1: 214.355968MB (obj cache: 136)
[9:9:20, Fri Jul 23, 2010] [0] Memory usage at end thread 3: 214.482944MB (obj cache: 136)
[9:9:20, Fri Jul 23, 2010] [0] Memory usage at idle thread 3: 214.482944MB (obj cache: 136)
[9:9:20, Fri Jul 23, 2010] [0] Memory usage at end thread 2: 214.482944MB (obj cache: 136)
[9:9:20, Fri Jul 23, 2010] [0] Memory usage at idle thread 2: 214.482944MB (obj cache: 136)
ACTUALIZACIÓN (8/12/2010): Sólo dirigió durante un día con una nueva versión compilada de Perl 5.12 con hilos y malloc sistema. Extrañamente, tengo el mismo comportamiento. Pierde trozos de MB a la vez, lentamente. Podría intentar Valgrind para ver por qué lo estoy perdiendo. Mientras estaba jugando con otra cosa, pensé en otra cosa. Mi script crea y destruye (supuestamente) muchos muchos sockets SSL. ¿Es posible que un módulo ampliamente utilizado como IO :: Socket :: SSL gotee un poco? ¿O tal vez OpenSSL? (Usando v0.9.8o). Intentando sincronizar el acceso al módulo SSL para ver si tiene algún efecto, puede haber problemas con los subprocesos que acceden a él.
ACTUALIZACIÓN: Se intentó cargar los módulos por separado dentro de cada hilo, un uso más rápido de la memoria. Intentó bloquear las áreas usando las funciones del socket para que solo un hilo a la vez las usara, aún así perdió la memoria de la misma manera que antes. Aumentó la cantidad de hilos de trabajo de 4 a 10 con la misma cantidad de trabajo. La memoria no duró 30 minutos. Me lleva a creer que es un problema de Perl internamente con su implementación de subproceso, o un problema de pila (sin juego de palabras intencionado). Traté de cambiar el tamaño de la pila usando los métodos de subprocesos incorporados pero el mismo resultado. Ir a buscar otra forma. Tal vez una forma de menor nivel. El aumento del número de hilos hace que la memoria ir más rápido ... parece ser algo con la implementación de pila los hilos o el tamaño de la pila
ACTUALIZACIÓN (9/15/2010): ha encontrado interesante esta golosina en el IO :: Socket :: SSL doc ...
Esto se debe al hecho de que se necesita una referencia circular para hacer que IO :: Socket :: SSL sockets actúen simultáneamente como objetos y referencias globales.
"Referencia circular" ¿eh? Otra explicación posible es que estos enchufes se mantienen por un tiempo aunque los descifre explícitamente. Ir a buscar en Weaken para ver si eso hace algo con los enchufes. Te dejaré saber si encuentro algo interesante.
SOLUCIONADO (9/16/2010): Véase mi respuesta que he publicado que contiene la solución
Publique un código o busque referencias circulares: P –
¿Ha mirado esta pregunta: http://stackoverflow.com/questions/429254/how-can-i-find-memory-leaks-in-long-running -perl-program – dwarring
posible duplicado de [Perl de perfiles de uso de memoria y detección de fugas?] (http://stackoverflow.com/questions/1359771/perl-memory-usage-profiling-and-leak-detection) – Ether