2012-01-03 12 views
11

En Java, ¿es posible que obtenga una excepción OutOfMemoryError, incluso cuando debería haber suficiente memoria en caso de que la recolección de basura liberara más memoria? En otras palabras, si no hay suficiente memoria para asignar, ¿se forzará la ejecución de gc antes de lanzar OutOfMemoryError?¿Es posible obtener OutOfMemoryError porque la recolección de basura es demasiado lenta?

Gracias.

+0

Niza pregunta, pero que yo sepa no hay ninguna manera se puede speedup GC mediante el establecimiento de los parámetros, excepto que marca su referencia a nula en el código. – kosa

Respuesta

0

El GC se general, tratar de encontrar la memoria antes de OutOfMemoryError se lanza, pero muy ocasionalmente que he visto ejemplos reproducibles donde el recolector de basura no acaba de mantener el ritmo, y una llamada a System.gc() impide la excepción.

Eso es muy la excepción (sin juego de palabras) en lugar de la regla, sin embargo, usted debe casi nunca tratar de provocar la recolección de basura usted mismo.

6

Hay un caso donde puede obtener un OOM que no está relacionado con el montón o el espacio de direcciones relacionado: es cuando la JVM decide que el GC tarda demasiado tiempo en ejecutarse.

Ver here.

En otras palabras, la respuesta a su pregunta original, es decir, "si no hay memoria suficiente para asignar, se forzará a ejecutar antes de arrojar el OutOfMemoryError", es sí.

(verá desde el enlace anterior que la relación es 98%/2% para GC/código que se ejecuta, que es muy alta ya)

(nota 2: esto es para Sun/JVM de Oracle , no hay idea para otras implementaciones)

5

puede obtenerlo si el GC gasta demasiado tiempo tratando de liberar memoria y no libera mucha memoria al hacerlo 'java.lang.OutOfMemoryError: el límite superior del GC excedido', consulte this question.

2

Se obliga a ejecutar el GC antes de que se genere OutOfMemoryError. Si la JVM implementa varias variedades de GC (como "concurrente" o "parcial"), se ejecutará una GC antes de que la JVM se rinda, por lo que se han realizado todos los esfuerzos posibles para evitar el error.

La excepción que se cita es que si el GC se ejecuta repetidamente y solo recupera una cantidad minúscula de almacenamiento (y el tamaño del almacenamiento dinámico no se puede expandir) arrojará la toalla en lugar de seguir funcionando en modo "rastreo" . En teoría, para este caso, aumentar ligeramente el tamaño del montón permitiría que una aplicación "buena" se ejecute bien, pero una aplicación que está masticando poco a poco (lo que no es inusual) no se beneficiaría de un ligero aumento del montón, y encontraría el misma falla solo un poco más tarde.

[Se debe observar que en los casos en GC está funcionando con demasiada frecuencia crecientes el tamaño del montón puede reducir significativamente overhead GC, si la aplicación se comporta bien y simplemente por casualidad pasa a estar funcionando cerca del límite del montón . (Por supuesto, aumentar el tamaño del almacenamiento dinámico a una RAM mayor que la habitual generalmente hará que la aplicación funcione más despacio.)]

Cuestiones relacionadas