Debe introducir al menos 3 caracteres en el buscador.
Inicio / Wikis / Tutoriales / Los rincones del API Win32: Los montones - ¿Cuantos montones debo crear?

Los rincones del API Win32: Los montones - ¿Cuantos montones debo crear?

 ****- (2 opiniones)
Creative Commons Tutorial de Juan Manuel - 27 de Agosto de 2005
Temas Relacionados: Programación estructurada
21. ¿Cuantos montones debo crear?
Un programador principiante, las únicas variables que utilizará son las almacenadas en la pila (locales) o las variables estáticas (globales). Según su conocimiento va aumentando, aprenderá a utilizar la asignación dinámica de memoria, sin embargo, lo que suele hacer es realizar todas las reservas en el montón por defecto, ya sea utilizando funciones del lenguaje (malloc, calloc, etc.), como funciones para montones locales y globales (LocalAlloc y GlobalAlloc). Un programador experto debe ir más allá, y detectar las situaciones en que es recomendable crear montones adicionales.

Utilizar múltiples montones puede incrementar el rendimiento, sobre todo poniendo énfasis en los siguientes puntos:

  • Un montón por cada hilo
    En situaciones de acceso masivo al montón, se puede producir un cuello de botella cuando múltiples hilos acceden al montón por defecto repetidas veces (miles o millones). En estas situaciones es recomendable crear un montón por cada hilo, y realizar todas las peticiones de memoria al montón privado de cada hilo. Además, en este caso se puede (y se debe) desactivar el mecanismo de sincronización de hilos (utilizando la bandera HEAP_NO_SERIALIZE), ya que será un solo hilo el que haga accesos a cada montón, y este mecanismo ralentiza la ejecución.

    Suponiendo que estamos programando un programa servidor, podríamos crear un hilo que gestione las peticiones de cada cliente que se conecta a nuestro servidor. Además, si estos hilos hacen un uso intensivo de la memoria dinámica, es muy recomendable crear un montón para cada uno de ellos, utilizando la bandera HEAP_NO_SERIALIZE en la llamada a HeapCreate.

  • Un montón para cada tipo de dato
    Si utilizamos el montón por defecto para almacenar estructuras de datos, lo más probable, como ya hemos explicado, es que después de las primeras asignaciones/liberaciones, tengamos un montón con bloques de memoria fragmentados. Para aclarar esto, nada mejor que un ejemplo: supongamos que tenemos un montón 140 KB y hacemos las siguientes reservas:

    1. Reservar 20 KB

    2. Reservar 10 KB

    3. Reservar 50 KB

    4. Reservar 40 KB


    Después de estas reservas, el aspecto del montón será el de la siguiente figura:



    Como puede verse, los bloques libres (aunque en realidad la memoria virtual que los soporta está reservada) se representan en blanco y los bloques reservados, en gris. Si después de estas operaciones liberamos el bloque de 10 KB, el aspecto del montón será el como se muestra a continuación:



    Este montón está fragmentado, ya que el espacio libre total es de 30 KB, pero si intentamos hacer una reserva con este tamaño, no lo conseguiremos, porque que no hay bloques contiguos suficientemente grandes. Si fuera un montón auto-extensible (como el montón por defecto), y se realizase una reserva de 30 KB, se tendría que crear un montón-hijo para acomodar este espacio, lo cual es una operación muy lenta.

    Esta situación, se podría evitar si utilizamos un montón por cada tipo de dato a almacenar.
    Supongamos que necesitamos almacenar dos listas enlazadas: la primera de elementos de 5 KB y la segunda de elementos de 7 KB. Si ambas listas se almacenan en el mismo montón, podríamos llegar fácilmente a situaciones como la descrita. Sin embargo, si utilizamos un montón para cada lista, los bloques siempre serán lo suficientemente grandes, porque los "huecos" serán siempre de un tamaño múltiplo del espacio requerido (5 y 7 KB respectivamente) y los nuevos bloques siempre "encajarán" en estos "huecos". En esta figura



    se muestra un montón fragmentado, pero que acomodaría perfectamente cualquier petición de 7 KB (representa el montón adicional para la segunda lista enlazada).

  • Situar los bloques de memoria próximos
    Es conveniente que los bloques de memoria que vayan a ser utilizamos a la vez se reserven dentro de un rango de direcciones virtuales lo más pequeño posible. Esto es debido a que, cuando el sistema necesita más memoria, vuelca cierto rango de páginas al archivo de intercambio para dejar espacio libre en RAM. Si los bloques de memoria que necesitamos no están próximos entre sí, puede darse el caso de que nuestros datos hayan sido volcados al archivo de intercambio, con lo cual sería necesario volverlos a recuperar de disco y proyectarlos en memoria, lo cual es una operación muy lenta. Utilizando un montón para cada estructura de datos, conseguimos que los bloques de memoria que se van a utilizar a la vez se direccionen juntos, con lo que minimizamos el riesgo de que algunos de ellos sean volcados al archivo de intercambio.

    En el ejemplo que pusimos anteriormente, es recomendable que los bloques de ambas listas enlazadas, se sitúen próximos entre sí dentro del sistema de memoria virtual, y esto se consigue utilizando un montón para cada una de ellas

  • Proteger componentes
    Si en el mismo montón, mezclamos bloques de memoria de distintas estructuras, corremos el riesgo de que una escritura errónea en la manipulación de una de ellas, pueda afectar a los datos de la otra. En nuestro ejemplo, si cometemos un error al manipular la primera lista enlazada, podemos sobrescribir datos de la segunda lista, lo cual sería difícil de depurar, máxime si ambas estructuras se utilizan desde partes muy distintas del programa. Es mucho más conveniente aislar cada una de las estructuras en su propio montón, para evitar así que un error en una parte de un programa, afecte a sus datos, y no a los datos de otros objetos.

    Este método es especialmente recomendable para proteger componentes encapsulados dentro de una DLL, ya que así nos aseguramos que no corromperemos la memoria del programa, sino la de nuestra propia DLL.

Autor y licencia de 'Los rincones del API Win32: Los montones - ¿Cuantos montones debo crear?'
Juan Manuel Extraído de: http://www.lawebdejm.com

Creative Commons License
Esta obra está bajo una licencia de Creative Commons.
Este contenido ha sido recopilado por el equipo de Wikilearning. Todo el contenido recopilado se ha obtenido respetando y comunicando en nuestro site la licencia de cada fuente.
Wikilearning tiene permiso expreso por escrito de los autores para publicar los contenidos que ha extraído de otras webs, incluyendo su uso comercial.

Wikis relacionados con 'Los rincones del API Win32: Los montones - ¿Cuantos montones debo crear?'

La organización funcional y burocratizada ha utilizado el conocimiento para codificarlo en procedimientos y rutinas,... Más »
Al hablar de antes, debo añadir que dispone usted de implantes que nunca le permitirán... Más »
Es muy fácil crear archivos en el sistema operativo UNIX. Por lo tanto, los usuarios... Más »
La transmisión de rumores es habitual dentro de las empresas. Los mensajes se distorsionan al... Más »
Curso sobre política, la práctica que se ocupa de gestionar, de resolver los conflictos colectivos... Más »
¿Estás seguro de que deseas eliminar este capítulo?