2012-09-06 28 views
15

En caso de que el montón esté lleno, la JVM arroja un OutOfMemoryError. ¿Pero se asegura que una recolección de basura (completa) siempre se lleva a cabo antes de que se produzca tal excepción?¿Está garantizado que el recolector de basura se ejecute antes de que se produzca un error de falta de memoria?

Esto significa que la memoria está llena solo con objetos de referencia fuertes (o accesible por GC Roots) cuando se lanza la excepción.

Editar: Supongamos que Sun JVM - HotSpot está en discusión.

+1

En java, es un "Error de memoria insuficiente" – arshajii

+0

@A. R. S .: De hecho, me di cuenta de esto cuando vi el comentario de la etiqueta 'outofmemoryexception', que hace referencia a .NET. He editado, gracias por el aviso. – m3th0dman

+0

Tengo curiosidad sobre por qué exactamente hace esta pregunta (no quiere decir que no fue razonable, sino para saber qué consideraciones está haciendo) – chiccodoro

Respuesta

19

El Java Machine Specification states in section 6.3 (el énfasis es mío):

OutOfMemoryError: El virtual Java la implementación de la máquina se ha agotado de ya sea la memoria virtual o física, y el administrador de almacenamiento automático no pudo recuperar suficiente memoria para satisfacer una solicitud de creación de objeto.

Así que la JVM da una garantía de que intentará todo lo que pueda para liberar memoria a través de la recolección de basura antes de arrojar un OOME.

2

No hay garantía de que la última operación anterior a OutOfMemoryError sea la recolección de basura. Lo más probable es que no, ya que la recolección de basura reduciría la cantidad de memoria utilizada y no la aumentaría.

+0

En este caso, existe la posibilidad de que desde un montón de 2 GB, tal vez 0,5 GB contenga objetos inalcanzables y se emite OutOfMemoryError incluso si, desde mi punto de vista (del programador), 1/4 del montón es gratuito. ¿Podría sugerir alguna referencia para esto? – m3th0dman

+0

* "Probablemente no, ya que la recolección de basura reduciría la cantidad de memoria utilizada, no la aumentaría" * a menos que no haya memoria que reclamar ... Varias respuestas sobre SO parecen decir lo contrario (es decir, que la JVM intentará liberarla) recursos con un GC antes de lanzar un OOE). – assylias

12

El colector de garaje normalmente se ejecutará antes de lanzar un OutOfMemoryError. Sin embargo es posible obtener una OOME sin GC si

  • intenta crear un objeto muy grande (por ejemplo, mayor que el montón)
  • iniciar un hilo y no hay suficiente memoria virtual o los recursos para iniciar el hilo .
  • versiones anteriores de Java lanzarían este error si alcanzas tu memoria directa máxima.
7

No se le garantiza que una recolección de basura lleno se ha realizado, pero que la máquina virtual ha tratado de hacer suficiente memoria disponible a través de la recolección de basura. Que podría haber encontrado que en el API documentation for the OutOfMemoryError class:

lanza cuando la Máquina Virtual de Java no puede asignar un objeto porque no tiene memoria, y no hay más memoria podría ser puesto a disposición por el recolector de basura.

Tenga en cuenta que hay casos en los que el recolector de basura puede decidir que no hay suficiente memoria disponible sin intentar realmente descartar instancias de objetos sin referencia. El ejemplo más obvio es si intenta asignar más memoria de una vez (por ejemplo, una matriz de bytes grande) que el tamaño máximo de almacenamiento dinámico. En este caso, se puede lanzar un OutOfMemoryError sin que se ejecute el recolector de elementos no utilizados.

2

Hay otros factores adicionales a considerar además de lo que las personas ya han respondido, por ejemplo, la política de recolección de basura que está utilizando. Tenga en cuenta la recolección de elementos no utilizados, esto arrojará una excepción de falta de memoria si se gasta demasiado tiempo en recopilar y no se libera suficiente memoria (aunque los cambios recientes podrían haber cambiado las cosas). Una vez dicho todo esto, no asumiría la recolección de basura se produce en cualquier momento dentro de la ejecución de una aplicación que estoy escribiendo ...

Cuestiones relacionadas