2009-04-20 21 views
6

Estoy ejecutando mi aplicación C++ en un dispositivo Intel Xscale. El problema es que cuando ejecuto mi aplicación offtarget (Ubuntu) con Valgrind, no muestra ninguna pérdida de memoria.Fuga de memoria en C++

Pero cuando lo ejecuto en el sistema de destino, comienza con 50K de memoria libre, y se reduce a 2K durante la noche. ¿Cómo atrapar este tipo de fuga, que Valgrind no muestra?

+0

¿Tiene algún código diferente? ¿Es realmente idéntico? Sí no, Cuál es la diferencia. Solo algunos pensamientos rápidos. –

+0

Supongo que quiere decir: comienza con 50 kb * gratis *? – MSalters

+0

Sí, comienza con 50 KB gratis. Sí, también hay algún código específico de plataforma. Pero lo desactivé mientras lo ejecutaba en el sistema ontarget. Pero, aún el mismo problema. – Ajay

Respuesta

3

Puede que no sea una pérdida de memoria real, pero tal vez una situación de uso de memoria cada vez mayor. Por ejemplo, podría ser la asignación de una cadena constante aumento:

string s; 
for (i=0; i<n; i++) 
    s += "a"; 

50k no es mucho, tal vez debería revisar su fuente a mano y ver lo que podría estar causando el problema.

+0

Bueno, en realidad comienza con 50K de memoria libre y termina con 2K de memoria libre. El código es aproximadamente de 1,00,000 líneas. – Ajay

+0

Bueno, solo se filtraron 48kB, lamento decir que si no es una fuga real, es posible que tengas que buscar el código de posibles culpables ... ¿qué hay de las asignaciones de memoria de registro? –

+0

Si valgrind no muestra fugas, este es el escenario más probable. Eso no quiere decir que sea el único, pero es una situación que valgrind no puede detectar. Lo mejor que puede hacer es escribir volcados de memoria en el disco a intervalos, y compararlos. Si encuentra un búfer que es más grande en cada volcado sucesivo, examine el código que lo rodea. Es tedioso, concedido ... –

3

Esto puede no ser una fuga, sino solo el montón de tiempo de ejecución que no libera memoria en el sistema operativo. Esto también puede ser fragmentación.

maneras posibles para superar esta:

  1. dividido en dos aplicaciones. La aplicación maestra tendrá la lógica simple con poco o ningún uso de memoria dinámica. Se iniciará la aplicación de trabajo para que realmente trabaje en tales fragmentos para que la aplicación de trabajo no se quede sin memoria y se reiniciará periódicamente. De esta forma, la memoria se devuelve periódicamente al sistema operativo.

  2. Escriba su propio asignador de memoria. Por ejemplo, puede asignar un montón dedicado y solo asignar memoria desde allí, luego liberar completamente el montón dedicado. Esto requiere que el sistema operativo sea compatible con múltiples montones.

También tenga en cuenta que es posible que su programa se ejecuta de manera diferente en Ubuntu y en el sistema de destino y se toman por lo tanto, diferentes rutas de ejecución y el código que resulta en pérdidas de memoria se ejecuta en el sistema de destino, pero no en Ubuntu.

+0

Pero, lo que sucede, el dispositivo Xscale, en un punto del tiempo, se queda sin memoria y luego la aplicación falla. Por lo tanto, es imprescindible detener la ingesta continua de memoria. ¿Puedes sugerir alguna manera? – Ajay

0

Si se reduce el uso de la memoria, no creo que pueda definirse como una pérdida de memoria. ¿Dónde está recibiendo informes de uso de memoria? El sistema podría haber utilizado la mayor parte del uso de la memoria de su programa en la memoria virtual.

¡Todo lo que puedo agregar es que Valgrind es bastante eficiente en la búsqueda de fugas de memoria!

0

Además, ¿está seguro de que cuando diseñó su código, la cobertura del código fue suficiente para cubrir todas las rutas de código que podrían ejecutarse en la plataforma de destino?

Valgrind seguro no miente. Como se ha señalado, este podría ser el montón de tiempo de ejecución que no libera la memoria, pero pensaría lo contrario.

0

¿Está utilizando alguna técnica sofisticada para rastrear el alcance del objeto ...? en caso afirmativo, que valgrind no es lo suficientemente inteligente, aunque se puede tratar mediante el establecimiento de la opción relacionada xscale con valgrind

+0

no tengo conocimiento de ninguna opción relacionada con xscale en valgrind. ¿Como hacer eso? – Ajay

0

mayoría de las aplicaciones muestran un patrón de uso de memoria como esto:

  • que utilizan muy poco cuando empiezan
  • , ya que crean estructuras de datos que utilizan más y más
  • a medida que empiezan eliminación de estructuras de datos antiguos o reutilizar las existentes, que llegan a un estado de equilibrio donde el uso de la memoria se mantiene más o menos constante

Si su aplicación aumenta continuamente en tamaño, puede tener aleak. Si aumenta en tamaño durante un período y luego alcanza un estado relativamente constante, probablemente no lo haga.

10

Un culpable común con estos pequeños elementos incrustados es la fragmentación de la memoria. Puede tener memoria libre en su aplicación entre 2 objetos. Una solución común a esto es el uso de un asignador dedicado (operador nuevo en C++) para las clases más comunes. Las agrupaciones de memoria utilizadas exclusivamente para objetos de tamaño N no se fragmentan: el espacio entre dos objetos siempre será un múltiplo de N.

1

Esto suena como fragmentación. La fragmentación se produce por que la asignación de los objetos en la pila, por ejemplo:

objeto1
objeto2
object3
object4

Y a continuación, eliminar algunos objetos

objeto1

object3
object4

Ahora tiene un agujero en la memoria que no se usa. Si asigna otro objeto que es demasiado grande para el hoyo, el hoyo seguirá siendo un desperdicio. Eventualmente, con suficiente memoria de abandono, puede terminar con tantos agujeros que pierden la memoria.

La solución a esto es intentar y decidir los requisitos de memoria por adelantado. Si tiene objetos particulares que sabe que está creando muchos, intente y asegúrese de que sean del mismo tamaño.

Puede usar una agrupación para hacer que las asignaciones sean más eficientes para una clase en particular ... o al menos permitirle hacer un seguimiento de la misma para que pueda comprender lo que está sucediendo y encontrar una buena solución.

Una forma de hacer esto es crear una sola estática:

struct Slot 
{ 
    Slot() : free(true) {} 
    bool free; 
    BYTE data[20]; // you'll need to tune the value 20 to what your program needs 
}; 
Slot pool[500]; // you'll need to pick a good pool size too. 

crear la agrupación en la delantera cuando el programa se inicia y antes de asignarlo de manera que es tan grande como los requisitos máximos para su programa . Es posible que desee HeapAlloc (o el equivalente en su sistema operativo para que pueda controlar cuándo aparece desde algún lugar en el inicio de la aplicación).

A continuación, anule los operadores nuevos y elimine para una clase sospechosa para que devuelvan las ranuras de este vector. Entonces, tus objetos serán almacenados en este vector.

Puede anular nuevo y eliminar para las clases del mismo tamaño para poner en este vector.

Cree grupos de diferentes tamaños para diferentes objetos.

Simplemente busque los peores delincuentes al principio.

He hecho algo así antes y resolvió mi problema en un dispositivo incrustado. También estaba usando un montón de STL, así que creé un asignador personalizado (google para stl asignador personalizado - hay muchos enlaces). Esto fue útil para los registros almacenados en una mini-base de datos que mi programa usó.

0

Puede usar la herramienta de macizo de Valgrind, que le mostrará dónde se asigna la mayor cantidad de memoria y cómo evoluciona con el tiempo.