2009-02-26 11 views
6

Tengo la necesidad de asignar grandes bloques de memoria con nuevos.Asignación de bloques grandes de memoria con el nuevo

Estoy atascado con el uso de nuevo porque estoy escribiendo un simulacro para el lado del productor de una aplicación de dos partes. El código real del productor está asignando estos bloques grandes y mi código tiene la responsabilidad de eliminarlos (después de procesarlos).

¿Hay alguna manera de asegurar que mi aplicación pueda asignar tanta cantidad de memoria del montón? ¿Puedo configurar el montón a un tamaño más grande?

Mi caso es 64 bloques de 288000 bytes. A veces obtengo 12 para asignar y otras veces obtengo 27 para asignar. Recibo una excepción std :: bad_alloc.

Esto es: C++, GCC en Linux (32 bits).

+0

¿Necesita todo eso de una vez? De lo contrario, podría usar un grupo de memoria y un asignador personalizado para administrar el grupo. – dirkgently

+0

Como dije, estoy tratando de burlarme de lo que hará el código de producción. Yo usaría un grupo de memoria asignado estáticamente si pudiera. – JeffV

+0

Puede usar un grupo asignado estáticamente y reemplazar sus llamadas para eliminar con una función 'FreeBlock'. De esta forma puede verificar que ha llenado cada bloque adquirido. –

Respuesta

9

Con respecto a nueva en C++/GCC/Linux (32 bits) ...

Ha sido un tiempo, y es dependiente de la implementación, pero creo nueva será, detrás de las escenas, invocar malloc(). Malloc(), a menos que solicite algo que exceda el espacio de direcciones del proceso, o fuera de los límites especificados (ulimit/getrusage), no fallará. Incluso cuando su sistema no tiene suficiente RAM + SWAP. Por ejemplo: malloc (1gig) en un sistema con 256 Meg de RAM + 0 Creo que SWAP tendrá éxito.

Sin embargo, cuando vaya a usar esa memoria, el núcleo suministrará las páginas a través de un mecanismo de asignación diferida. En ese punto, cuando lee o escribe por primera vez en esa memoria, si el kernel no puede asignar páginas de memoria a su proceso, mata su proceso.

Esto puede ser un problema en una computadora compartida, cuando su colega tiene una fuga de núcleo lento. Especialmente cuando comienza a noquear los procesos del sistema.

El hecho de que esté viendo excepciones std :: bad_alloc es "interesante".

Ahora nuevo ejecutará el constructor en la memoria asignada, tocando todas esas páginas de memoria antes de que regrese. Dependiendo de la implementación, podría atrapar la señal de falta de memoria.

¿Has probado esto con malloc?

¿Ha intentado ejecutar el programa "libre"? ¿Tienes suficiente memoria disponible?

Como han sugerido otros, ¿ha comprobado límite/ulimit/getrusage() para hard & restricciones suaves?

¿Cómo se ve tu código, exactamente? Supongo new ClassFoo [N]. O quizás nuevo carácter [N].

¿Qué es sizeof (ClassFoo)? ¿Cuál es N?

La asignación de 64 * 288000 (17.58 Meg) debería ser trivial para la mayoría de las máquinas modernas ... ¿Se ejecuta en un sistema integrado o algo especial?

O bien, ¿está enlazando con un nuevo nuevo asignador? ¿Su clase tiene su propio nuevo asignador?

¿Su estructura de datos (clase) asigna otros objetos como parte de su constructor?

¿Alguien ha manipulado sus bibliotecas? ¿Tienes múltiples compiladores instalados? ¿Estás utilizando las rutas de acceso o biblioteca incorrectas?

¿Está vinculado a archivos de objetos obsoletos? ¿Simplemente necesita recompilar todos sus archivos fuente?

¿Se puede crear un programa de prueba trivial? ¿Solo un par de líneas de código que reproducen el error? ¿O es tu problema en otra parte, y solo aparece aquí?

-

Por lo que vale la pena, he asignado más bloques de datos 2gig con nuevo en Linux de 32 bits bajo g ++. Tu problema está en otra parte.

+1

+1 para el desglose completo! – JeffV

4

Es posible que esté limitado por el proceso 'ulimit; ejecute ulimit -a y verifique la memoria virutal y los límites de tamaño del segmento de datos. Aparte de eso, ¿puedes publicar tu código de asignación para que podamos ver lo que está sucediendo realmente?

+0

Comprobé usando getrlimit (RLIMIT_AS, & lim), está informando 4GB en el actual y máximo. – JeffV

+0

@Jeff: ¡solo intentas asignar aproximadamente 18Mb! Esa es una miseria en cualquier computadora moderna. Debe * haber * algo más asignando toneladas de memoria dentro de su programa. –

0

sugiero asignar toda su memoria al inicio del programa y usar la ubicación nueva para ubicar sus memorias intermedias. ¿por qué este enfoque? bueno, puedes hacer un seguimiento manual de la fragmentación y demás. no hay una forma portátil de determinar cuánta memoria se puede asignar a su proceso. Estoy seguro de que hay una llamada al sistema específica de Linux que te dará esa información (no puedo pensar en qué es). buena suerte.

0

El hecho de que tenga un comportamiento diferente cuando ejecuta el programa en diferentes momentos me hace pensar que el código de asignación no es el problema real. En cambio, alguien más está usando la memoria y usted es el canario que descubre que falta.

Si ese "alguien más" está en su programa, debería poder encontrarlo usando Valgrind.

Si ese alguien es otro programa, deberías poder determinarlo yendo a un runlevel diferente (aunque no necesariamente conocerás al culpable).

1

Actualización:

ya que he fijado un error de indexación de matrices y se está asignando correctamente ahora.

Si tuviera que adivinar ... estaba caminando sobre mi montón y estaba jugando con las estructuras de datos de malloc. (??)

+0

¡Eso sin duda lo haría! Algunas veces utilizo métodos de acceso INLINED con declaraciones de afirmación para detectar estos problemas durante la fase de depuración. (Se compilan para el código de producción). –

Cuestiones relacionadas