2011-04-30 11 views
5

Con la compilación estática, solo las funciones de una biblioteca que realmente necesita un programa están vinculadas al programa. ¿Cómo es eso con las bibliotecas compartidas? ¿Las funciones realmente necesarias para un programa se cargan en la memoria mediante el vinculador dinámico o siempre se carga la biblioteca compartida total? Si se trata de funciones, ¿cómo podría obtener el tamaño real de un programa, incluidas sus funciones cargadas durante el tiempo de ejecución?C, C++: Bibliotecas compartidas: ¿Se cargan en la memoria funciones individuales o bibliotecas completas?

Gracias! Oliver

+0

Buena pregunta ...No tengo idea de cuál es la respuesta, porque nunca tuve que pensar en ello ... lo cual plantea la pregunta contraria "¿Por qué crees que esto es importante?" ;-) Ergo: ¿Cuál es tu problema real? Danos algo de contexto. – corlettk

+2

Si las bibliotecas se comparten, pueden ser utilizadas por varios programas al mismo tiempo. ¿Cómo se cuenta eso? –

+1

Cuando se carga una lib compartida en la memoria, ¿agrega tamaño a su ejecutable? ¿Quién sabe? La biblioteca compartida podría ser cargada en la memoria y reutilizada (en la misma ubicación) por todas las aplicaciones. Incluso si encuentra una respuesta, eso no significa que se mantendrá en el futuro. Cada sistema operativo puede cambiar y optimizar el manejo de las bibliotecas compartidas. Esto está tan fuera de la especificación de cualquier lenguaje que aterrice únicamente en el sistema operativo. –

Respuesta

2

Cuando realiza una vinculación estática, solo las funciones que (potencialmente) reciben se vinculan al ejecutable, pero en el tiempo de ejecución, los datos del archivo ejecutable serán leídos en la memoria por demanda de búsqueda.

Cuando se crea el proceso, las direcciones se asignan a todo el código en las bibliotecas ejecutables y compartidas para ese proceso, pero el código/datos del archivo no se leen necesariamente en la memoria física en ese momento. Cuando intente acceder a una dirección que no está actualmente en la memoria física, activará una excepción no presente. El administrador de memoria virtual del sistema operativo reaccionará a eso al leer la página del archivo en la memoria física, que dejar que proceda el acceso.

La carga se realiza página por página, lo que generalmente significa bloques de 4 u 8 kilobytes a la vez (por ejemplo, x86 usa páginas de 4K, Alpha usa 8k). x86 también tiene la capacidad de crear páginas más grandes (4 megabytes), pero esas no son (al menos usualmente) usadas para código normal; son para mapear grandes bloques de memoria que permanecen mapeados (semi) permanentemente, tales como la "ventana" de memoria en una tarjeta gráfica típica que también está mapeada para que la CPU pueda acceder directamente a ella.

La mayoría de los cargadores tienen algunas optimizaciones, así que (por ejemplo) que van a tratar de leer los bloques más grandes de la memoria cuando el programa se pone en marcha inicialmente. Esto permite que comience más rápido que si hubiera una interrupción y lectura separada para cada página de código a medida que se accede. Los detalles exactos de esa optimización varían entre sistemas operativos (y, a menudo, incluso versiones del mismo sistema operativo).

6

Con la compilación estática, solo las funciones de una biblioteca que realmente necesita un programa están vinculadas al programa. ¿Cómo es eso con las bibliotecas compartidas?

El programa hace referencia simbólicamente a las bibliotecas compartidas, es decir, el programa identificará, por nombre, la biblioteca compartida con la que se vinculó.

¿Las funciones realmente necesarias para un programa se cargan en la memoria mediante el vinculador dinámico o siempre se carga la biblioteca compartida total?

El programa hará referencia a los puntos de entrada y los objetos de datos específico en la biblioteca compartida. La biblioteca compartida será mapeados en memoria como un único objeto grande, pero sólo las páginas que se hace referencia en realidad se localizará en el kernel. La cantidad total de la biblioteca que se carga dependerá de la densidad de las referencias, las referencias de otras imágenes vinculadas a ella y la ubicación de la propia funcionalidad de la biblioteca.

Si se trata de funciones, ¿cómo podría obtener el tamaño real de un programa, incluidas sus funciones cargadas durante el tiempo de ejecución?

La mejor manera en Mac y otros sistemas basados ​​en Unix es con ps (1).

+0

¡Muchas gracias por su respuesta! Si lo entiendo correctamente, solo se cargan las páginas que tienen el código de las funciones necesarias. ¿Significa eso, para los sistemas integrados, que si tuviera solo una pequeña RAM pero grandes bibliotecas (que pueden, por ejemplo, no cabe en la memoria RAM), que todavía pudiera ejecutar el exectuable (en Linux)? – Oliver

+0

Sí eso es lo que significa (recuerde aprobar la respuesta si cree que responde a su pregunta). Aunque realmente debe planificar para el peor de los casos y asegurarse de que no se quede sin memoria, no importa a qué funciones llama en sus dependencias. –

+0

@Oliver: tal vez. Debido a que la granularidad de la página es aproximada, una imagen dinámica cargará muchos bits que usted nunca usa, y la biblioteca en sí misma probablemente toque mucho más funcionalidad de la que debería incluso para "hola, mundo". Es una solución difícil, los enlaces estáticos usan menos memoria para una aplicación, pero significa que las bibliotecas no se comparten con otros programas y demonios del sistema vinculados por separado. Me gustaría vincular estáticamente cualquier biblioteca utilizada una sola vez y cargar dinámicamente las compartidas por los servicios esenciales. Tenga en cuenta que * puede * ejecutar múltiples copias de la misma imagen estática sin una penalización de memoria. – DigitalRoss

Cuestiones relacionadas