2012-08-30 22 views
7

Tengo un programa que acepta datos de un socket, realiza algún control de calidad y otros acondicionamientos variados, luego los escribe en un conducto con nombre. Ejecuté valgrind en él y solucioné todas las pérdidas de memoria que originalmente existían. Luego creé un entorno 'demo' en un sistema en el que tenía 32 instancias de este programa ejecutándose, cada una alimentada con datos únicos y cada salida a su propio conducto. Lo probamos y todo parecía estar bien. Luego probé a hacer pruebas de estrés aumentando la velocidad a la que los datos se envían a un ritmo absurdo y las cosas parecían estar bien al principio ... pero mis programas seguían consumiendo más y más memoria hasta que no me quedaban recursos.cómo buscar la pérdida de memoria valgrind dice que no existe?

Me volví a valgrind y ejecuté exactamente la misma configuración, excepto con cada programa ejecutándose dentro de valgrind usando leak-check = full. Algunas cosas raras sucedieron. En primer lugar, la memoria se filtró, pero solo hasta el punto en que cada programa había consumido el .9% de mi memoria (anteriormente la memoria más grande tenía un 6% de mi memoria). Con valgrind corriendo el costo de CPU de los programas se disparó y ahora estaba al 100% de la CPU con un promedio de carga enorme, así que es posible que la falta de CPU disponible hiciera que todos los programas funcionaran lo suficientemente lento como para que la fuga tardara demasiado en manifestarse . Cuando traté de detener estos programas, valgrind no mostró fugas directas de memoria, mostró algunas posibles pérdidas de memoria, pero las revisé y no creo que ninguna de ellas represente fugas de memoria reales; y además, la posible pérdida de memoria solo mostraba unos pocos kilobytes mientras el programa consumía más de 100 MB. La memoria alcanzable (no filtrada) informada por valgrind también estaba en el rango de KB, por lo que valgrind parece creer que mis programas consumen una fracción de la memoria que Top dice que están usando.

He realizado algunas otras pruebas y obtuve resultados extraños. Un solo programa, incluso funcionando al triple de la velocidad a la que se detectó mi fuga de memoria original, nunca parece consumir más del 0,9% de memoria, dos programas pierden hasta 1.9 y 1.3% de memoria respectivamente, pero no más, etc., es como si el la cantidad de memoria filtrada, y la velocidad a la que se filtra, de alguna manera depende de cuántas instancias de mi programa se ejecutan a la vez; lo cual no tiene sentido, cada instancia debe ser 100% independiente de las demás.

También encontré si ejecuto 32 instancias con solo una instancia ejecutándose en valgrind la instancia valgrinded (¡eso es una palabra si digo que lo es!) Pierde memoria, pero a un ritmo más lento que las que se ejecutan fuera de valgrind. La instancia de valgrind seguirá diciendo que no tengo filtraciones directas e informa mucho menos consumo de memoria que la que muestra Top.

Estoy bastante perplejo en cuanto a qué podría estar causando este resultado, y por qué valgrind se niega a ser consciente de la pérdida de memoria. Pensé que podría ser una biblioteca externa, pero realmente no uso ninguna biblioteca externa; solo funciones/objetos básicos de C++. También consideré que podrían ser los datos escritos en la tubería de salida de rápido haciendo que el búfer crezca indefinidamente, pero 1) debería haber un límite superior para que ese búfer pueda crecer y 2) una vez que se haya filtrado la memoria si dejo caer los datos velocidad de entrada a nada, la memoria permanece consumida en lugar de volver a caer lentamente a una cantidad razonable.

¿Alguien puede darme una pista sobre dónde debo mirar desde aquí? Estoy totalmente perplejo de por qué la memoria se está comportando de esta manera.

Gracias.

+2

¿Estás seguro de que es una pérdida, y no solo una parte de tu memoria de programación? ¿Has probado el macizo? – PlasmaHH

+0

Me he topado con problemas similares (aunque no tan peculiar) y estoy muy interesado en cualquier comentario que reciba. Una sugerencia: ¿podría aclarar el sistema operativo/versión que está utilizando? Supongo que es un dist de Linux. –

+0

Valgrind ejecuta su programa en un entorno limitado y realiza una gran cantidad de procesamiento. Debería esperar que tenga un uso de CPU mucho mayor y un rendimiento mucho más lento que la misma aplicación que se está quedando sin valgrind. Consideraría si durante las pruebas de estrés el programa crea búferes adicionales para contener datos que no pudieron llegar a la tubería y que están creciendo (no se filtraron, sino que crecen porque no se puede mantener el ritmo). –

Respuesta

1

Esto suena como un problema que tuve recientemente.

Si su programa acepta datos y los almacena en búfer internamente sin ningún límite, entonces puede estar leyendo y almacenando en búfer más rápido de lo que puede generar los datos. En ese caso, el uso de la memoria continuará aumentando sin límite.

Cuantas más instancias del programa ejecute, más lenta será cada instancia y más rápido aumentarán las memorias intermedias.

Esto puede o no ser su problema, pero sin más información es lo mejor que puedo hacer.

+0

Esto fue lo más cercano a la precisión. Se suponía que debía generar datos una vez cada x segundos (confugados por un archivo de configuración). Pero debido a un error, el contador que almacenaba mi tiempo de espera se incrementaba al inicio, así que estaba almacenando un minuto + de datos. La tensión adicional en el sistema causó que el error que incrementaba mi contador de tiempo de espera ocurriera más a menudo al inicio. Me gustaría dar las gracias a Plasma por mencionar el macizo que me puso en la dirección correcta. Pensé que memcheck me decía que no se usaba mucha memoria, así que no miré el uso de la memoria interna; Aparentemente leí mal a memcheck. – dsollen

2

Primero debe buscar una fuga blanda. Ocurre cuando algo estático o singleton aumenta gradualmente algún buffer o contenedor y recoge basura en él. Técnicamente no es una fuga, pero sus efectos son tan malos.

1

¿Puedo sugerirle que pruebe con MemoryScape? Esta herramienta hace un buen trabajo en la detección de fugas de memoria. No es gratis, pero dado el tiempo y la energía gastados, vale la pena intentarlo.

Cuestiones relacionadas