2009-02-05 9 views
15

¿Por qué el jvm requiere alrededor de 10 MB de memoria para un mundo hello simple pero el clr no? ¿Cuál es la compensación aquí, es decir, qué gana la jvm al hacer esto?jvm design decision

Déjenme aclarar un poco porque no estoy transmitiendo la pregunta que está en mi cabeza. Claramente hay una diferencia arquitectónica entre los tiempos de ejecución jvm y clr. El jvm tiene una huella de memoria significativamente más alta que el clr. Supongo que hay algún beneficio con esta sobrecarga; de lo contrario, ¿por qué existiría? Pregunto cuáles son las compensaciones en estos dos diseños. ¿Qué beneficio obtiene el jvm de su carga de memoria?

+1

¿Cómo sabes que está sobrecargado? ¿Hiciste un programa esqueleto en cada uno y los ejecutaste? Solo puedo conseguir que la JVM tome alrededor de 7 mb en el arranque (según el Administrador de tareas), incluso con -Xmx256m-Xms256m. –

+0

¿Puede darnos una clase de prueba que utilizó en ambos? Esto ayudará a reproducir el problema y, por lo tanto, dar buenas respuestas. –

+0

No creo que mi pregunta fuera clara, así que solo la edité. Para una clase de prueba, una simple aplicación HelloWorld. – jshen

Respuesta

6

Supongo que una razón es que Java tiene que hacer todo por sí mismo (otro aspecto de la independencia de la plataforma). Por ejemplo, Swing dibuja sus propios componentes desde cero, no depende del sistema operativo para dibujarlos. Eso tiene que suceder en la memoria. Muchas de las cosas que windows pueden hacer, pero Linux no tiene (o tiene algo diferente) que estar contenido en Java para que funcione igual en ambos.

Java también siempre insiste en que toda la biblioteca está "Vinculada" y disponible. Como no usa archivos DLL (no estarían disponibles en todas las plataformas), todo tiene que ser cargado y rastreado por Java.

Java incluso hace mucho de su propio punto flotante ya que las FPU a menudo dan resultados diferentes que se han considerado inaceptables.

Así que si piensas en todo lo que C# puede delegar en el sistema operativo al que está vinculado vs todo lo que Java tiene que hacer para el sistema operativo para compensar a los demás, la diferencia debería esperarse.

Ahora he ejecutado aplicaciones Java en 2 plataformas integradas. Uno era un analizador de espectro en el que dibujaba las trazas, el otro era decodificadores de cable.

En ambos casos, esta huella mínima de memoria no ha sido un problema - HAN habido problemas específicos de Java, que simplemente no ha sido uno. La cantidad de objetos instanciados y la velocidad de pintura Swing fueron problemas mayores en estos casos.

1

CLR se cuenta como parte del sistema operativo, por lo que el administrador de tareas no informa su consumo de memoria en el proceso de solicitud.

+0

Si uso mono en unix, todavía se usa solo unos pocos megas en comparación con 30 para el jvm – jshen

+2

El CLR comienza dentro de cada proceso, por lo que dudo que esta respuesta sea correcta. – Austin

+1

Austin: hay una instancia de CLR en cada uno de los procesos. Con CLR y JRE, el código de solo lectura se comparte entre los procesos. La pregunta es: ¿se cuenta ese código para cada proceso o para ningún proceso? –

2

La JVM cuenta todas sus bibliotecas compartidas, ya sea que usen memoria o no.

El administrador de tareas no es confiable a la hora de informar el consumo de memoria de los programas. Debes tomarlo como una guía.

+1

El otro día mi máquina Vista de 4 GB se quedó sin memoria a pesar de aparecer mostrar menos de 1 GB utilizado por las aplicaciones. –

+0

No uso ventanas, así que no uso el administrador de tareas – jshen

5

Parece que java solo está usando más memoria virtual.

USER  PID %CPU %MEM VSZ RSS TTY  STAT START TIME COMMAND 
amwise 20598 0.0 0.5 22052 5624 pts/3 Sl+ 14:59 0:00 mono Test.exe 
amwise 20601 0.0 0.7 214312 7284 pts/2 Sl+ 15:00 0:00 java Program 

Hice un programa de prueba en C# y en Java que imprime la cadena "prueba" y espera para la entrada. Creo que el valor del tamaño del conjunto residente (RSS) muestra con mayor precisión el uso de la memoria. El uso de memoria virtual (VSZ) es menos significativo.

Según tengo entendido, las aplicaciones pueden reservar una tonelada de memoria virtual sin utilizar ninguna memoria real. Por ejemplo, puede solicitar la función VirtualAlloc en Windows para reservar o confirmar la memoria virtual.

EDIT:

Aquí está una imagen bonita de mi caja de ventanas: alt text http://awise.us/images/mem.png

Cada aplicación fue un printf sencilla seguido de un getchar. Mucha memoria virtual utilizada por Java y CLR. La versión C depende de casi nada, por lo que su uso de memoria es relativamente pequeño.

Dudo que realmente importe de ninguna manera. Simplemente elija la plataforma con la que esté más familiarizado y luego no escriba un código terrible que desperdicia la memoria. Estoy seguro de que funcionará.

EDIT:

Este VMMap tool de Microsoft podría ser útil en figureing dónde va la memoria.

+2

RSS de un proceso inactivo tampoco es una gran medida. –

+0

No estoy tratando de decidir qué plataforma es mejor para mí. Tengo curiosidad de por qué tomaron la decisión de diseño que hicieron en el lado jvm, y lo que obtuvieron de él. – jshen

+0

Todo el uso de memoria en un espacio de proceso es virtual (al menos en Windows). En un sistema operativo de 32 bits, el espacio de direcciones se divide en 2 GB de código y 2 GB de datos. Total de bytes privados se refiere a la cantidad asignada en el espacio de direcciones de datos de la aplicación. El SO maneja cómo esta asignación se relaciona con la memoria física. –

5

No sé si la huella de memoria inicial o la huella de una aplicación Hello World es importante. Una diferencia puede deberse a la cantidad y el tamaño de las bibliotecas cargadas por JVM/CLR. También puede haber una cantidad de memoria preasignada para los grupos de recolección de basura.

Cada aplicación que conozco utiliza mucho más que la funcionalidad Hello World. Eso cargará y liberará memoria miles de veces durante la ejecución de la aplicación.Si usted está interesado en las diferencias de utilización de la memoria de JVM vs CLR, aquí hay un par de enlaces con buena información

http://benpryor.com/blog/2006/05/04/jvm-vs-clr-memory-allocation/

Memory Management Case study (JVM & CLR)

Estudio de caso de gestión de memoria se encuentra en Power Point. Una presentación muy interesante.

+0

claramente no estoy diciendo mi pregunta claramente. No estoy interesado en las diferencias de utilización de la memoria. Estoy tratando de descubrir por qué el jvm requiere mucha más memoria para iniciar que esencialmente todos los otros tiempos de ejecución del lenguaje de programación que he usado. Supongo que hay una razón para ello, y tengo curiosidad por saber qué es. – jshen

+0

Dudo que fuera demasiado intencional. La potencia real de un lenguaje basado en máquinas virtuales se muestra cuando la aplicación implementa lógica comercial y se ejecuta durante un período de tiempo. Los parámetros de inicio (Utilización inicial de la memoria y Tiempo de inicio) generalmente se consideran de importancia secundaria. Una cosa que puedo pensar es que el número inicial de bibliotecas que se cargan al inicio es diferente entre JVM y CLR. JVM puede cargar más por adelantado que CLR cargando más a pedido. En el largo plazo, eso no hace mucha diferencia –

2

JVM carga muchas clases principales innecesarias en cada ejecución desde rt.jar. Desafortunadamente, las dependencias internas (java.lang < -> java.io) de los paquetes java hacen que sea difícil hacer un inicio parcial en tiempo de ejecución. Sin mencionar que el rt.jar mismo tiene más de 40MB, necesita mucho tiempo para buscar y descomprimir.

Post Java 6u10 parece cargar cosas un poco más inteligente (tiene un servicio de arranque rápido jqs.exe = java para mantener los datos necesarios en la memoria y hacer un inicio más rápido), aún así se dice que Java 7 es mejor.

El Explorador de procesos en Windows informa los Bytes privados correctamente (Los bytes privados son aquellas regiones de memoria que no se comparten con ninguna dll).

Una molestia un poco más grande es que, después de 10 años, JVM aún usa de manera predeterminada 64MB de memoria. Es realmente molesto usar -Xmx casi todas las veces y no puedo ejecutar programas exigentes en frascos con un simple doble clic (a menos que modifique el comando de la asignación de extensión de archivo).