2012-06-25 20 views
21

Estoy buscando un poco más en el modelo de memoria y estoy luchando por comprender cuántos montones existen en un proceso.Asignación de pilas y montones

Entonces, si tenemos 1 proceso con 5 hilos en él, ¿estoy en lo correcto al decir que tendríamos 5 pilas y 1 montón?

Si es así, pueden los subprocesos acceder a las pilas de los demás (o es exactamente por eso que tienen pilas separadas, para evitar daños), y si hay solo 1 montón, obviamente todos acceden a este montón, de ahí la necesidad de bloqueo con múltiples hilos? ¿Estoy entendiendo esto correctamente?

Respuesta

31

Sí, cada subproceso tiene su propia pila. Esa es una necesidad difícil, la pila realiza un seguimiento de dónde regresa un método una vez que termina, almacena la dirección de devolución. Como cada subproceso ejecuta su propio código, necesitan su propia pila. Las variables locales y los argumentos del método se almacenan allí también, por lo que (normalmente) son seguros para subprocesos.

El número de montones es un detalle más complicado. Está contando 1 para el montón recogido de basura. Eso no es del todo correcto desde el punto de vista de la implementación, los tres montones generacionales más el Montículo de objetos grandes son montones lógicamente distintos, y suman hasta cuatro. Este detalle de implementación comienza a importar cuando asigna demasiado.

Otro que no puede ignorar por completo en el código administrado es el montón que almacena las variables estáticas. Está asociado con AppDomain, variables estáticas en vivo mientras viva el AppDomain. Comúnmente llamado "montón de cargador" en la literatura de .NET. En realidad, consta de 3 montones (alta frecuencia, baja frecuencia y pila de stub), el código jit y los datos de tipo también se almacenan allí, pero eso está llegando al fondo.

Más abajo en la lista de ignorar están los montones utilizados por el código nativo. Dos de ellos son fácilmente visibles desde la clase Marshal. Hay un montón de proceso predeterminado, Windows asigna desde allí, también lo hace Marshal.AllocHGlobal(). Y hay un montón separado donde COM almacena datos, Marshal.AllocCoTaskMem() los asigna. Por último, cualquier código nativo con el que interactúes tendrá su propio montón para su soporte en tiempo de ejecución. El número de montones utilizados por ese tipo de código está limitado solo por la cantidad de archivos DLL nativos que se cargan en su proceso. Todos estos montones existen, casi nunca lidias con ellos directamente.

Por lo tanto, 10 montones mínimo.

12

En resumen, .

Todos los hilos en un proceso comparten el mismo montón, por lo que pueden intercambiar datos. Cada hilo tiene su propia pila que se relaciona con la ejecución del código actual en este hilo.

Un recurso muy bueno en la rosca está aquí: http://www.albahari.com/threading/

Un hilo es análogo al proceso del sistema operativo en el que su ejecuta la aplicación. Así como los procesos se ejecutan en paralelo en una computadora, los hilos se ejecutan en paralelo dentro de un único proceso. Los procesos están totalmente aislados entre sí; los hilos tienen un grado limitado de aislamiento . En particular, los subprocesos comparten la memoria (montón) con otros subprocesos que se ejecutan en la misma aplicación. Esto, en parte, explica por qué es útil el subprocesamiento : un hilo puede recuperar datos en segundo plano, para la instancia , mientras que otro hilo puede mostrar los datos a medida que llegan.

+1

Gracias por el excelente enlace, muy buen recurso para tener. – Richard

2

Esta es la implementación definida, pero hablemos de los sistemas operativos modernos más populares, ya que agrega la etiqueta C#.

cuántos paquetes existen en un proceso.

Normalmente 1 por proceso.

Así que si tenemos 1 proceso con 5 hilos en ella, estoy en lo correcto al decir que tendríamos 5 pilas y 1 montón?

Sí. Cada subproceso consume 1 MB de espacio de direcciones virtual directamente para la pila de subprocesos.

Si es así, ¿pueden los hilos de acceder a uno pilas de otro (o esto es exactamente por qué tienen separada Pilas, para prevenir la corrupción), y si sólo hay 1 montón, entonces, evidentemente, que todos los accesos a este montón, de ahí la necesidad para el bloqueo con múltiples hilos? ¿Estoy entendiendo esto correctamente?

Sí, los entornos modernos están muy bien aislados, por lo tanto, no se puede acceder directamente a otra pila de subprocesos desde otra secuencia.

+0

Lukas ¿viste a Jakub-Konecki responder? ¿Cómo se correlaciona con "... por lo tanto, no se puede acceder a otra pila de hilos"? ¿Y por qué existe un mecanismo de "bloqueo"? – Jasper

+0

Seguramente puede acceder a la pila de un hilo desde otro, aunque es mucho mejor evitar tales comunicaciones directas y usar una cola de objetos a la que se pueda acceder desde ambos hilos. –

+1

Nitpicking: un proceso tiene el Heap administrado (normal), un Heap de objetos grandes y podrías considerar el Heap no gestionado como # 3. –

4

Los hilos son secuencias de instrucciones separadas que se ejecutan simultáneamente en el mismo espacio de direcciones virtuales de un solo proceso. El montón es una gran parte de la memoria que el sistema otorga a cada proceso para su uso privado. Los procesos pueden ajustar su tamaño de almacenamiento dinámico y pueden usar el espacio de almacenamiento dinámico que consideren necesario.Los subprocesos pueden colaborar en el uso de este espacio de montón y también pueden asignar regiones de memoria privada adicionales conocidas como almacenes locales de subprocesos (TLSes).

Dado que todos los subprocesos comparten el mismo espacio de direcciones virtuales, pueden acceder directamente a la memoria de las pilas de los demás. Esto significa que un hilo puede pasar una variable en su pila como argumento para una función que se ejecuta en otro hilo. Pero aún las pilas de hilos están separadas porque un hilo nunca empuja o coloca valores en la pila de otro hilo, sino solo en su propio espacio de pila. Como las pilas en x86 y x86-64 crecen hacia abajo, hay una página especial en la parte inferior de la memoria de la pila de cada hilo: la llamada página de protección . El error de pila ocurre si se alcanza la página de protección mientras se opera la pila.

En los idiomas no administrados como C y C++, se puede acceder a cualquier parte de la memoria del proceso a voluntad mediante el uso de punteros. Un hilo puede estropear completamente el contenido de la pila de otro hilo y, por lo tanto, bloquear el segundo hilo (y el proceso en su conjunto). En C#, este tipo de cosas no pueden suceder fuera de los bloques unsafe ya que las pilas están gestionadas por el CLR.

+0

_un hilo puede pasar una variable en su pila como argumento para una función que se ejecuta en otro hilo_ - ¿cómo harías eso exactamente? –

+0

Con Win32 hilos podría simplemente iniciar un nuevo hilo y pasar la dirección de una variable local en el hilo actual como el argumento de hilo. También podría usar 'PostThreadMessage' para enviar un mensaje a un hilo ya en ejecución. –

+0

Ambos enfoques requerirían un puntero. –

Cuestiones relacionadas