2008-11-19 17 views
22

Viniendo de un fondo de Java, una de las cosas a las que estoy acostumbrado es decirle a la JVM cuál debe ser el tamaño máximo de almacenamiento dinámico. Si el programa en ejecución intenta tragar más de lo permitido y el recolector de basura no puede liberar más recursos, se lanza OutOfMemoryError y todo se vuelve loco. Por lo tanto, establecer el tamaño máximo de almacenamiento dinámico es importante en Java.¿Puedo (y alguna vez quiero) establecer el tamaño de almacenamiento dinámico máximo en .net?

¿Esto se aplica en .net? ¿Puede establecer los límites de tamaño de almacenamiento dinámico? ¿El CLR simplemente sigue creciendo hasta que alcanza los límites físicos de la máquina? ¿O no es un problema en .net por algún motivo sutil que mis luces de fondo de Java me impiden ver?

Respuesta

19

No puede establecer el tamaño de almacenamiento dinámico máximo en .Net a menos que usted mismo aloje el CLR en un proceso.

Editar: Para controlar las asignaciones de memoria de CLR, incluyendo el tamaño máximo del montón, es necesario utilizar la API de hosting para alojar el CLR y, específicamente, utilizar las "interfaces gestor de memoria", algo de información de arranque se puede encontrar aquí MSDN Magazine, column CLR Inside Out : CLR Hosting APIs

Editar: para responder a su pregunta, ¿por qué querría controlar la asignación de memoria o, específicamente, el tamaño máximo de almacenamiento dinámico, generalmente no desea, pero si está escribiendo una aplicación que es como SQL Server o IIS o alguna aplicación en tiempo real, entonces tendría una buena razón para tener control sobre la memoria y, específicamente, evitar la paginación; de lo contrario, la CLR y el sistema operativo ya le hacen un trabajo bastante bueno, y lo que queda es asegurar que esa aplicación use recursos mínimos para que las cosas funcionen bien.

+0

Gracias - información interesante sobre el alojamiento de CLR. Probablemente exagerado por lo que estoy haciendo ahora. Solo me aseguraré de no ser un cerdo de memoria. – serg10

+1

Los entornos de servidores compartidos que alojan varias aplicaciones deben garantizar que la memoria máxima asignada por todas sus aplicaciones de cliente no exija en exceso la memoria disponible. No quiere que una sola aplicación que funciona mal descuelgue todo el servidor porque asigna toda la memoria disponible. –

+2

@Kelly, eso es lo que hacen IIS y SQL Server, porque son hosts para otras aplicaciones administradas, y controlan cuánta memoria tienen permitidas las aplicaciones alojadas ... por otro lado, una aplicación .Net no alojada es gratuita para asignar tanto como una aplicación nativa, no hay diferencia allí (es por eso que en .net las APIS de alojamiento se deben usar para controlar la cantidad de memoria asignada) –

12

No, no se aplica en .NET. El montón de hecho sigue creciendo hasta que ya no puede crecer. (Obviamente, esto es "después de intentar recuperar memoria a través de GC, hacer crecer el montón"). Básicamente, no hay tanta afinación disponible en el GC de .NET como en Java. Puede elegir el servidor GC o el cliente, y creo que hay una opción para activar/desactivar el GC concurrente (encontraré enlaces en un minuto), pero eso es básicamente.

EDIT: Parece que hay un poco más, aunque no es una gran cantidad. Rick Minerich's blog entry on GC settings y the subsequent one parecen saber más que yo sobre el asunto. Probablemente sean un buen punto de partida para cualquier investigación adicional, pero en su mayoría son banderas más que el tipo de límites de memoria disponibles en JVM.

EDITAR: La respuesta de Pop plantea un buen punto: he estado asumiendo un modelo de alojamiento CLR "normal" (es decir, no bajo su control). Si desea hacer el esfuerzo de alojarlo usted mismo, es probable que obtenga mucho más control, a costa del trabajo adicional de alojarlo. No puedo decir que haya mirado ese lado de las cosas.

4

Por lo que he encontrado, no hay una manera simple de control the size of the heap de una aplicación .Net usando el CLR.

El enlace arriba solo la mitad responde la pregunta. Cuando investigué este mismo problema, la respuesta es "El montón crece para usar toda la memoria disponible" como si esa fuera la única razón por la que deseara controlar el tamaño máximo de almacenamiento dinámico.

En entornos de servidor (normalmente Java), no desea que una aplicación de mal comportamiento acapare la memoria a expensas de otras aplicaciones alojadas. Una solución simple es limitar la cantidad de memoria que la aplicación puede usar para su montón. Esto se logra con el argumento -Xmx de Java para que pueda garantizar que la aplicación no usará más de lo que está planificado, p. Ej. -Xmx256M.Dado que asignar memoria en el montón durante la inicialización puede ralentizar el inicio de las aplicaciones, Java usa el argumento -Xms para permitir que las aplicaciones que hacen mucha creación de objetos durante la inicialización comiencen con un gran bloque de almacenamiento dinámico en lugar de que la JVM cambie el tamaño del montón va.

.Net's CLR no tiene esta capacidad. Sospecho que es porque .Net's CLR no es una máquina virtual. El CLR pasa a ser una API (bastante completa, podría agregar) que sirve como un adaptador para .dlls nativos que equivale a un enfoque mucho más parecido a un ejecutable cuando se trata de la administración de la memoria.

He hecho esta pregunta sobre el desarrollo de SharePoint y oí que es posible controlar el amperaje mediante el uso de módulos IIS llamados Aplicaciones Web por lo que puede decirle a IIS que limite la memoria de una aplicación web determinada. Me pregunto si esto se debe a que IIS tiene rutinas personalizadas que reemplazan/anulan new()/malloc()/etc y así pueden proporcionar este tipo de control a las aplicaciones cliente. Eso significa que las aplicaciones .Net independientes no tienen éxito a menos que desee escribir un administrador de memoria personalizado en C++ y crear una interfaz para .NET

Cuestiones relacionadas