2010-08-02 6 views
6

Me encuentro con un problema extraño que he podido rastrear un poco, pero todavía no puedo ver la causa. Tal vez alguien aquí puede arrojar algo de luz?Oddity de asignación de memoria de clase de subprocesos en una plataforma incrustada

Estoy ejecutando un procesador PowerPC sobre VxWorks 5.5 desarrollando en C++ con la cadena de herramientas PPCgnu604.

que tienen una clase de esta manera:

class MyClass 
{ 
    public: 
    void run(void); 
    private: 
    CommandMesssageClass command; 
    StatusMessageClass status; 
}; 

Cuando se inicia mi solicitud, se asignará dinámicamente una instancia de MyClass y generará un subproceso que apunta a su función "run". Básicamente, se queda ahí sondeando los comandos y, una vez recibidos, emitirá un estado de nuevo.

Tenga en cuenta que esta es una versión reducida de la clase. Hay una serie de otros métodos y variables omitidos para la brevedad.

El problema que veo es cuando tanto el comando como los mensajes de estado se definen como miembros privados de la clase. Obtendré un cambio en los bytes disponibles en la memoria a pesar de que no debe haber asignación de memoria dinámica. Esto es importante porque esto está ocurriendo en lo que debe ser un procedimiento determinista y seguro para las tasas.

Si muevo una o ambas declaraciones de mensajes a la función de ejecución, funciona bien sin ninguna asignación adicional.

Debo perderme algo fundamental en mi comprensión de las declaraciones de C++ y la asignación de memoria. Según entiendo, una instancia de clase que instase dinámicamente se asignará por completo en el montón (incluidas todas las variables miembro) cuando se cree. La diferencia que veo aquí sería que mover las declaraciones de mensajes a la función de ejecución las pone en la pila en su lugar. El montón en este caso es más que suficiente para acomodar todo el tamaño de la clase. ¿Por qué parece que no se está asignando suficiente memoria hasta que se utilizan porciones específicas?

Las clases de mensaje no tienen asignaciones dinámicas propias. (Y si lo hicieran, esperaría que mover la declaración no cambiara el comportamiento en este caso y aún vería un cambio en el tamaño del montón.)

Para supervisar la asignación de memoria estoy usando lo siguiente VxWorks memLib (o memPartLib) llamada:

memPartInfoGet(memSysPartId, &partitionStatus); 
... 
bytesFree = partitionStatus.numBytesFree; 

Editar:

Para aclarar, el objeto MyClass se instansiated y se inicializa en una rutina de inicialización y luego el código entra procesamiento tasa de fallos. Durante este tiempo, al recibir un mensaje de comando a través de una línea serie (la primera interacción con los objetos de mensaje Comando o Estado) se asigna memoria adicional (o más bien disminuye el número de bytes libres). Esto es malo porque la asignación de memoria dinámica no es determinista.

He podido eliminar el problema moviendo las variables de clase como he descrito.

+0

No está muy claro cuál es su problema, ¿es que usted usa más memoria asignando las cosas como miembros de la clase vs en la pila, o es que la memoria utilizada varía con el tiempo en uno de los casos? – nos

+1

¿sizeof (MyClass) cambia cuando levanta los miembros a la sección pública? ¿Y cuánto cambia la asignación de memoria? –

+1

* ¿Cuándo * cambia la asignación? Los objetos de clase más pequeños tienen un tiempo más fácil de encajar en un bloque libre en el montón. –

Respuesta

2

Debo estar perdiendo algo fundamental en mi comprensión de C++ declaraciones y la asignación de memoria.

No lo creo. Todo lo que dices que esperas arriba es correcto: los programadores de juegos dependen en gran medida de este comportamiento todo el tiempo.:-)

¿Por qué parece que no debe asignar memoria suficiente hasta se utilizan porciones específicas ?

Has dejado las agallas de la clase por la brevedad. He tenido cierta experiencia en la depuración de problemas similares, y mi mejor estimación es que en algún lugar allí una función de biblioteca es, de hecho, haciendo una asignación de tiempo de ejecución que usted no conoce.

En otras palabras, la asignación de tiempo de ejecución está ahí en ambos casos, pero los dos tamaños diferentes de MyClass significan que las agrupaciones de malloc se rellenan de forma diferente. Puedes probar esto moviendo los objetos a la pila dentro de run(), pero rellenando MyClass con el mismo tamaño. Si todavía ves la caída libre de mem, entonces no tiene nada que ver con si esos objetos están en el montón o la pila ... es un efecto secundario que está sucediendo debido al tamaño de MyClass.

Recuerde, malloc es grumoso: la mayoría de las implementaciones no hacen asignaciones uno a uno para cada llamada a malloc. En su lugar, sobre asigna y mantiene la memoria en un grupo, y crece esos grupos cuando sea necesario.

No estoy familiarizado con su cadena de herramientas, pero los sospechosos típicos de pequeñas asignaciones inesperadas en sistemas integrados incluyen funciones ctype (locales) y funciones de fecha/hora (zona horaria).

Cuestiones relacionadas