Pregunta

Acabo de comenzar a experimentar con SDL en C ++, y pensé que verificar las pérdidas de memoria regularmente puede ser un buen hábito para formarse desde el principio.

Con esto en mente, he estado ejecutando mis programas 'Hello world' a través de Valgrind para detectar cualquier fuga, y aunque he eliminado todo excepto el SDL_Init () y más básicos > Declaraciones SDL_Quit () , Valgrind aún informa 120 bytes perdidos y 77k aún accesibles.

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

¿Fue útil?

Solución

Tenga cuidado de que Valgrind no esté captando falsos positivos en sus mediciones.

Muchas implementaciones ingenuas de analizadores de memoria señalan la pérdida de memoria como una pérdida cuando en realidad no lo es.

Tal vez lea algunos de los artículos en la sección de enlaces externos de 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 al intentar detectar pérdidas de memoria y luego se describen las técnicas que utiliza Purify para solucionar los problemas.

Por cierto, no estoy afiliado a IBM de ninguna manera. Acabo de usar Purify ampliamente y responderé por su efectividad.

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

HTH.

saludos,

Rob

Otros consejos

Debe tener cuidado con la definición de " pérdida de memoria " ;. Algo que se asigna una vez en el primer uso y se libera en la salida del programa, a veces se muestra mediante 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, es razonable que lo ejecute una vez, luego borre el detector de fugas y lo vuelva a ejecutar (por supuesto, esto requiere un control programático del detector de fugas). Cosas que " fugas " una vez por ejecución del programa generalmente no importa. Cosas que '' gotean '' cada vez que se ejecutan generalmente importan eventualmente.

Rara vez me ha resultado demasiado difícil alcanzar el cero en esta métrica, lo que equivale a observar el uso de memoria progresiva en lugar de bloques perdidos. Tenía una biblioteca donde estaba tan complicada, con cachés y muebles de interfaz de usuario y todo eso, que simplemente ejecuté mi suite de pruebas tres veces, e ignoré cualquier " fugas " Lo que no ocurrió en múltiplos de tres bloques. Todavía atrapé todas o casi todas las fugas reales, y analicé los informes complicados una vez que conseguí quitarme la fruta que colgaba. Por supuesto, las debilidades de usar el conjunto de pruebas para este propósito son (1) que solo puede usar las partes que no requieren un proceso nuevo y (2) la mayoría de las fugas que encuentra son culpa del código de prueba , no el código de la biblioteca ...

Vivir con pérdidas de memoria (y otros problemas descuidados) es, en el mejor de los casos, (en mi opinión) una programación muy mala. En su peor momento hace que el software sea inutilizable

Debe 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, el mundo no necesita otro.

EDITAR

Estoy de acuerdo: muchas herramientas pueden proporcionar falsos positivos.

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

Necesitas probar tu aplicación en una hora, y luego calcular la memoria filtrada. De esta manera, obtienes un valor de bytes de memoria / minuto filtrados.

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

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

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

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

La mayoría de los sistemas operativos (incluido Windows) devolverán toda la memoria asignada de un programa cuando se descargue el programa. Esto incluye cualquier memoria que el programa en sí haya perdido.

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

Entonces, realmente la pregunta no es si está perdiendo cualquier memoria, sino si la está perdiendo continuamente durante el tiempo de ejecución de su programa. Si usa su programa por un tiempo, y no importa lo que haga, permanece en 120 bytes perdidos en lugar de aumentar, diría que lo ha hecho muy bien. Sigue adelante.

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

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

  

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

Bueno, con Valgrind, " memoria accesible todavía " A menudo no se filtra realmente la memoria, especialmente en un programa tan simple. Puedo apostar con seguridad que básicamente no hay asignación en SDL_Quit (), por lo que " filtraciones " son solo estructuras asignadas una vez por SDL_Init ().

Intente agregar trabajo útil y ver si esas cantidades aumentan; intente hacer un ciclo de trabajo útil (como crear y destruir alguna estructura SDL) y ver si la cantidad de fugas aumenta con la cantidad de iteraciones. En este último caso, debe verificar los rastros de pila de las fugas y corregirlas.

De lo contrario, esas pérdidas de 77k cuentan como " memoria que debe liberarse al final del programa, pero para la cual confían en el sistema operativo para liberarla.

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

De acuerdo con los comentarios de Rob Wells sobre Purify, descargue y pruebe algunas de las otras herramientas disponibles. Utilizo 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 podría estar en un componente de terceros, que tal vez desee excluir de su análisis. Por ejemplo, MFC tenía varias pérdidas de memoria en las primeras versiones de vista.

OMI, las pérdidas de memoria deben rastrearse para detectar cualquier código que ingrese a una base de códigos que pueda tener una larga vida útil. Si no puede localizarlos, al menos haga una nota de que existen para el siguiente usuario del mismo código.

Las primeras pérdidas de memoria son solo un problema grave cuando crecen con el tiempo, de lo contrario, la aplicación parece un poco más grande desde el exterior (obviamente, aquí también hay un límite, por lo tanto, "grave"). Cuando tienes una fuga que crece con el tiempo, puedes tener problemas. Sin embargo, la cantidad de problemas depende 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á bien. Sin embargo, si no sabe a dónde va la memoria, no enviaría el programa y seguiría cavando.

Con SDL en Linux en particular, parece que hay algunas filtraciones en la biblioteca subyacente de X windows. No hay mucho que puedas hacer al respecto (a menos que quieras intentar arreglar la biblioteca en sí, lo que probablemente no sea para los de corazón débil).

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

En general, tenemos que ser un poco más indulgentes con las bibliotecas de terceros; Si bien no debemos aceptar pérdidas de memoria en nuestro propio 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 informarlas) al responsable de la biblioteca).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top