outofmemoryerror espacio dinámico almacenamiento java memory memory-management jvm out-of-memory

outofmemoryerror - Entendiendo la asignación de memoria JVM y Java sin memoria: espacio de almacenamiento dinámico



java lang outofmemoryerror espacio de almacenamiento dinámico de java (4)

¿Cómo se asigna realmente la JVM la memoria para sí misma?

Para el montón, asigna una gran región de memoria con el tamaño máximo. Inicialmente, esto es memoria virtual, sin embargo, con el tiempo se convierte en memoria real para las partes que se utilizan, bajo el control del sistema operativo

¿Cómo se relaciona esto con la forma en que el sistema operativo comunica la memoria disponible a la JVM?

La JVM no tiene idea acerca de la memoria libre en el sistema operativo.

O más generalmente, ¿cómo funciona realmente la asignación de memoria para cualquier proceso?

En general utiliza malloc y libre.

¿Cómo entra en juego la memoria virtual?

Inicialmente, se asigna memoria virtual y esto se convierte en memoria real como se usa. Esto es normal para cualquier proceso.

Digamos que tiene un sistema con 32 GB de memoria física y que asigna los 32 GB a su proceso Java.

Usted no puede El sistema operativo necesita algo de memoria y habrá memoria para otros propósitos. Incluso dentro de la JVM, el montón es solo una parte de la memoria utilizada. Si tiene 32 GB de memoria, le sugiero como máximo de 24 GB de pila.

Digamos que su proceso realmente consume todos los 32 GB de memoria,

Digamos que tiene 48 GB y comienza un proceso que utiliza 32 GB de memoria principal.

¿Cómo podemos imponer el proceso para utilizar la memoria virtual en lugar de ejecutar excepciones de OOM?

La aplicación utiliza la memoria virtual desde el principio. No puede hacer que el montón sea demasiado grande porque si comienza a intercambiar su máquina (no solo su aplicación) se volverá inutilizable.

Puede usar más memoria de la que tiene físicamente utilizando la memoria de almacenamiento dinámico, con cuidado. Sin embargo, la memoria administrada debe estar en la memoria física, por lo que si necesita un montón de 32 GB, compre 64 GB de memoria principal.

Estoy estudiando realmente cómo funciona la asignación de memoria en la JVM. Estoy escribiendo una aplicación en la que me estoy quedando sin memoria: excepciones de espacio de almacenamiento dinámico.

Comprendo que puedo pasar argumentos de VM como Xms y Xmx para aumentar el espacio de almacenamiento dinámico que JVM asigna para el proceso en ejecución. Esta es una posible solución al problema, o puedo inspeccionar mi código para detectar pérdidas de memoria y corregir el problema allí.

Mis preguntas son:

1) ¿Cómo asigna la JVM la memoria para sí misma? ¿Cómo se relaciona esto con la forma en que el sistema operativo comunica la memoria disponible a la JVM? O más generalmente, ¿cómo funciona realmente la asignación de memoria para cualquier proceso?

2) ¿Cómo entra en juego la memoria virtual? Digamos que tiene un sistema con 32 GB de memoria física y que asigna los 32 GB a su proceso Java. Digamos que su proceso en realidad consume todos los 32 GB de memoria. ¿Cómo podemos imponer el proceso para utilizar la memoria virtual en lugar de ejecutar excepciones de OOM?

Gracias.


  1. La JVM asigna la memoria del montón de Java desde el sistema operativo y luego administra el montón para la aplicación de Java. Cuando una aplicación crea un nuevo objeto, la JVM asigna un área contigua de memoria del montón para almacenarla. Un objeto en el montón al que hace referencia cualquier otro objeto está "vivo" y permanece en el montón mientras siga siendo referenciado. Los objetos que ya no están referenciados son basura y pueden eliminarse del montón para reclamar el espacio que ocupan. La JVM realiza una recolección de basura (GC) para eliminar estos objetos, reorganizando los objetos que quedan en el montón.
    Fuente: http://pubs.vmware.com/vfabric52/index.jsp?topic=/com.vmware.vfabric.em4j.1.2/em4j/conf-heap-management.html

  2. En un sistema que utiliza memoria virtual, la memoria física se divide en páginas de igual tamaño. La memoria direccionada por un proceso también se divide en páginas lógicas del mismo tamaño. Cuando un proceso hace referencia a una dirección de memoria, el administrador de memoria recupera del disco la página que incluye la dirección a la que se hace referencia y la coloca en una página física vacía en la RAM.

Fuente: http://searchstorage.techtarget.com/definition/virtual-memory



La JVM (o cualquier otro proceso) que desee asignar memoria llamará a la función " malloc " en tiempo de ejecución de C. Esta función mantiene la memoria del montón del tiempo de ejecución de C. A su vez, obtiene memoria del kernel del sistema operativo; la función utilizada para esto depende de la plataforma; en Linux podría estar usando las llamadas al sistema brk o sbrk .

Una vez que la JVM ha obtenido la memoria, administra la memoria misma, asignando partes de ella a los diversos objetos creados por el programa en ejecución.

La memoria virtual es manejada completamente por el núcleo del sistema operativo. El núcleo gestiona la asignación de páginas de memoria física al espacio de direcciones de varios procesos; Si hay menos memoria física de la que necesitan todos los procesos en el sistema, entonces el Kernel del SO cambiará parte de ella al disco.

No se puede (y no es necesario) forzar a los procesos a utilizar la memoria virtual. Es transparente a su proceso.

Si obtiene errores de falta de memoria, es probable que las causas sean:

  1. Se están excediendo los límites de JVM. Estos están controlados por diversos argumentos y / o propiedades de la línea de comando como lo indicó en su pregunta

  2. Es posible que el sistema operativo se haya quedado sin espacio de intercambio (o que no haya configurado ningún espacio de intercambio para comenzar). O algunos sistemas operativos ni siquiera admiten memoria virtual, en cuyo caso se ha quedado sin memoria real.

  3. La mayoría de los sistemas operativos tienen recursos para que el administrador limite la cantidad de memoria consumida por un proceso, por ejemplo, en Linux, la setrlimit sistema setrlimit y / o el comando ulimit shell, que establecen límites que el núcleo observará. Si un proceso solicita más memoria que la permitida por los límites, entonces el intento fallará (generalmente esto resulta en un mensaje de falta de memoria).