c++ memory-leaks sdl

c++ - ¿Hay un límite aceptable para las pérdidas de memoria?



memory-leaks sdl (11)

Acabo de comenzar a experimentar con SDL en C ++, y pensé que buscar fugas de memoria con regularidad puede ser una buena costumbre de formarse desde el principio.

Con esto en mente, he estado ejecutando mis programas de ''Hola mundo'' a través de Valgrind para detectar cualquier fuga, y aunque he eliminado todo, excepto las SDL_Init() más básicas SDL_Init() y SDL_Quit() , Valgrind aún informa 120 bytes perdidos y 77k todavía accesible.

Mi pregunta es: ¿hay un límite aceptable para las pérdidas de memoria, o debo esforzarme para que todo mi código esté completamente libre de fugas?


La mayoría de los sistemas operativos (incluido Windows) devolverán toda la memoria asignada de un programa cuando el programa esté descargado. Esto incluye cualquier memoria de la cual el programa puede haber perdido la pista.

Dado que, mi teoría habitual es que está perfectamente bien filtrar la memoria durante el inicio, pero no está bien hacerlo durante el tiempo de ejecución.

Así que realmente la pregunta no es si está perdiendo memoria, sino si la filtra continuamente durante el tiempo de ejecución de su programa. Si usas tu programa por un tiempo, y no importa lo que hagas, se queda en 120 bytes perdidos en lugar de aumentar, yo diría que lo has hecho genial. Siga adelante.


Parece que los desarrolladores de SDL no usan Valgrind, pero básicamente solo me preocupan esos 120 bytes perdidos.

Con esto en mente, he estado ejecutando mis programas de ''Hola mundo'' a través de Valgrind para detectar cualquier fuga, y aunque he eliminado todo, excepto las declaraciones más básicas SDL_Init () y SDL_Quit (), Valgrind aún informa 120 bytes perdidos y 77k todavía accesible.

Bueno, con Valgrind, "memoria alcanzable" a menudo no es realmente una memoria filtrada, especialmente en un programa tan simple. Puedo apostar con seguridad que básicamente no hay asignación en SDL_Quit (), por lo que las "fugas" son solo estructuras asignadas una vez por SDL_Init ().

Intente agregar trabajo útil y vea si esos montos aumentan; intente hacer un ciclo de trabajo útil (como crear y destruir alguna estructura de SDL) y ver si la cantidad de filtraciones crece con la cantidad de iteraciones. En este último caso, debe verificar los restos de la pila de fugas y corregirlos.

De lo contrario, esas fugas de 77k cuentan como "memoria que debe liberarse al final del programa, pero para lo cual dependen del sistema operativo para liberarla".

Entonces, en realidad, ahora estoy más preocupado por esos 120 bytes, si no son falsos positivos, y por lo general son pocos. Los falsos positivos con Valgrind son en su mayoría casos en los que se pretende el uso de memoria no inicializada (por ejemplo, porque en realidad es relleno).


Con SDL en Linux en particular, parece que hay algunas filtraciones en la biblioteca subyacente de X Windows. No hay mucho que pueda hacer al respecto (a menos que quiera intentar arreglar la biblioteca en sí, lo que probablemente no sea para los débiles).

Puede usar el mecanismo de supresión de valgrind (consulte --suppressions y --gen-supressions en la página man de valgrind) para decirle que no le moleste con estos errores.

En general, tenemos que ser un poco más indulgentes con las bibliotecas de terceros; aunque no debemos aceptar fugas de memoria en nuestro código, y la presencia de pérdidas de memoria debe ser un factor al elegir entre bibliotecas alternativas de terceros, a veces no hay más remedio que ignorarlas (aunque puede ser una buena idea denunciarlas) al mantenedor de la biblioteca).


Vivir con filtraciones de memoria (y otros problemas descuidados) es, en el mejor de los casos, (en mi opinión) una programación muy mala. En el peor de los casos, hace que el software no se pueda usar.

Debería evitar introducirlos en primer lugar y ejecutar las herramientas que usted y otros han mencionado para tratar de detectarlos.

Evite la programación descuidada, ya hay suficientes programadores malos por ahí, el mundo no necesita otro.

EDITAR

Estoy de acuerdo: muchas herramientas pueden proporcionar falsos positivos.


Debe tener cuidado con la definición de "pérdida de memoria". Algo que se asigna una vez en el primer uso, y liberado al salir del programa, a veces se mostrará por un detector de fugas, porque comenzó a contar antes de ese primer uso. Pero no es una fuga (aunque puede ser un mal diseño, ya que puede ser algún tipo de global).

Para ver si un fragmento dado de código tiene fugas, puede ejecutarlo razonablemente una vez, luego borrar el detector de fugas y luego ejecutarlo nuevamente (esto, por supuesto, requiere control programático del detector de fugas). Las cosas que "pierden" una vez por ejecución del programa generalmente no importan. Las cosas que "gotean" cada vez que se ejecutan generalmente sí importan eventualmente.

Raramente encuentro muy difícil llegar a cero en esta métrica, lo que es equivalente a observar el uso progresivo de la memoria en lugar de bloques perdidos. Tenía una biblioteca donde se ponía tan complicada, con cachés y muebles de interfaz de usuario, y otras cosas, que acababa de ejecutar mi suite de pruebas tres veces e ignoraba las "filtraciones" que no ocurrían en múltiplos de tres bloques. Todavía capturé todas o casi todas las filtraciones reales, y analicé los informes engañosos una vez que saqué la fruta más barata del camino. Por supuesto, las debilidades del uso del conjunto de pruebas para este propósito son (1) solo puede usar las partes que no requieren un nuevo proceso, y (2) la mayoría de las filtraciones que encuentra son culpa del código de prueba , no el código de la biblioteca ...


Depende de su aplicación. Algunas fugas pueden ser inevitables (debido al tiempo necesario para encontrar la fuga frente a las fechas límite). Siempre que su aplicación se ejecute todo el tiempo que desee y no tome una gran cantidad de memoria en ese momento, probablemente esté bien.


Las fugas de memoria iniciales son solo un problema serio cuando crecen con el tiempo, de lo contrario, la aplicación se ve un poco más grande desde el exterior (obviamente, aquí también hay un límite, de ahí el ''serio''). Cuando tienes una fuga que crece con el tiempo, es posible que tengas problemas. Sin embargo, cuántos problemas dependen de las circunstancias. Si sabe a dónde va la memoria y puede asegurarse de que siempre tendrá suficiente memoria para ejecutar el programa y todo lo demás en esa máquina, todavía está bastante bien. Sin embargo, si no sabe a dónde va la memoria, no enviaría el programa y seguiría excavando.


Para una aplicación de escritorio, pequeñas pérdidas de memoria no son un problema real. Para servicios (servidores), no se permiten pérdidas de memoria.


Según los comentarios de Rob Wells sobre Purify, descargue y pruebe algunas de las otras herramientas disponibles. Uso BoundsChecker y AQTime, y he visto diferentes falsos positivos en ambos a lo largo de los años. Tenga en cuenta que la pérdida de memoria también puede estar en un componente de un tercero, que es posible que desee excluir de su análisis. Por ejemplo, MFC tenía una cantidad de pérdidas de memoria en las primeras versiones de vista.

OMI, las fugas de memoria deben rastrearse para cualquier código que vaya a una base de código que puede tener una larga vida útil. Si no puede rastrearlos, al menos anote que existen para el siguiente usuario del mismo código.


Si realmente está preocupado por la pérdida de memoria, tendrá que hacer algunos cálculos.

Debe probar su aplicación durante aproximadamente una hora y luego calcular la memoria filtrada. De esta forma, obtienes un valor de memoria / minuto filtrado de memoria.

Ahora, necesitará estimar la duración promedio de la sesión de su programa. Por ejemplo, para notepad.exe, 15 minutos me parece una buena estimación.

Si ( longitud de sesión promedio) * (bytes filtrados / minuto)> 0.3 * (espacio de memoria normalmente ocupado por su proceso) , entonces probablemente debería hacer más esfuerzos para reducir las pérdidas de memoria. Acabo de inventar 0.3, use el sentido común para determinar su umbral aceptable.

Recuerde que un aspecto importante de ser programador es ser Ingeniero de Software, y muy a menudo la Ingeniería trata de elegir la opción menos mala entre dos o más opciones malas. Las matemáticas siempre son útiles cuando necesitas medir qué tan mala es la opción.


Tenga cuidado de que Valgrind no recoja falsos positivos en sus mediciones.

Muchas implementaciones ingenuas de los analizadores de memoria indican que la memoria se pierde como una fuga cuando en realidad no es así.

Tal vez leer algunos de los artículos en la sección de enlaces externos del artículo de Wikipedia sobre Purify . Sé que la documentación que viene con Purify describe varios escenarios en los que se obtienen falsos positivos cuando se intenta detectar fugas de memoria y luego se describen las técnicas que utiliza Purify para resolver los problemas.

Por cierto, no estoy afiliado a IBM de ninguna manera. Acabo de utilizar Purify extensamente y garantizaré su efectividad.

Editar: Aquí hay un excelente artículo introductorio que cubre el monitoreo de la memoria. Es específico de Purify, pero la discusión sobre los tipos de errores de memoria es muy interesante.

HTH.

aclamaciones,

Robar