poi outofmemoryerror exceeded error compressed java garbage-collection out-of-memory

exceeded - Cómo reproducir Java OutOfMemoryError-Se excedió el límite de sobrecarga del GC



java out memory error (3)

Como no has aceptado ninguna respuesta, asumiré que ninguno de ellos ha funcionado para ti. Aquí hay uno que lo hará. Pero primero, una revisión de las condiciones que provocan este error :

El recolector paralelo lanzará un OutOfMemoryError si se está gastando demasiado tiempo en la recolección de basura: si se pasa más del 98% del tiempo total en la recolección de basura y se recupera menos del 2% del montón

Por lo tanto, tiene que consumir casi todo el montón, mantenerlo asignado y luego asignar mucha basura. Poner muchas cosas en un Map no va a hacer esto por ti.

public static void main(String[] argv) throws Exception { List<Object> fixedData = consumeAvailableMemory(); while (true) { Object data = new byte[64 * 1024 - 1]; } } private static List<Object> consumeAvailableMemory() throws Exception { LinkedList<Object> holder = new LinkedList<Object>(); while (true) { try { holder.add(new byte[128 * 1024]); } catch (OutOfMemoryError ex) { holder.removeLast(); return holder; } } }

El método consumeAvailableMemory() llena el montón con porciones de memoria relativamente pequeñas. "Relativamente pequeño" es importante porque la JVM colocará objetos "grandes" (512k bytes en mi experiencia) directamente en la generación titular, dejando a la generación joven vacía.

Después de haber consumido la mayor parte del montón, simplemente asigno y descarto. El tamaño de bloque más pequeño en esta fase es importante: sé que tendré suficiente memoria para al menos una asignación, pero probablemente no más de dos. Esto mantendrá el GC activo.

Ejecutar esto produce el error deseado en menos de un segundo:

> java -Xms1024m -Xmx1024m GCOverheadTrigger Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded at GCOverheadTrigger.main(GCOverheadTrigger.java:12)

Y, para completar, aquí está la JVM que estoy usando:

> java -version java version "1.6.0_45" Java(TM) SE Runtime Environment (build 1.6.0_45-b06) Java HotSpot(TM) 64-Bit Server VM (build 20.45-b01, mixed mode)

Y ahora mi pregunta para ti: ¿por qué demonios querrías hacer esto?

Mi enfoque fue crear cien mil colecciones locales y poblarlas con cadenas aleatorias, algo como esto:

SecureRandom random = new SecureRandom(); for(int i = 0 ; i < 100000 ; i++){ HashMap<String, String> map = new HashMap<String, String>(); for(int j = 0 ; j < 30 ; j++){ map.put(new BigInteger(130, random).toString(32), new BigInteger(130, random).toString(32)); } }

También proporcioné el parámetro -XX: + UseGCOverheadLimit jvm, pero no puedo obtener el error. ¿Hay alguna forma fácil y confiable / hack para obtener este error?


Creo que esto debería hacer el truco ... si lo ejecutas el tiempo suficiente:

HashMap<Long, String> map = new HashMap<Long, String>(); for (long i = 0; true; i++) { for (int j = 0; j < 100; j++) { String s = "" + j; map.put(i, s); } }

Lo que estoy haciendo es aumentar lentamente la cantidad de no basura, al mismo tiempo que se crea una cantidad significativa de basura al mismo tiempo. Si esto se ejecuta hasta que la no basura llene casi todo el montón, el GC llegará a un punto donde el% de tiempo de recolección de basura excede el umbral.


Esta:

HashMap<String, String> map = new HashMap<String, String>();

tiene un ámbito dentro del bucle y no hay referencias externas (a largo plazo) al mapa creado a medida que el bucle se repite. Por lo tanto, cada mapa será elegible para la recolección de basura al final de cada iteración de bucle.

Debe crear una colección de objetos fuera del bucle y usar el bucle para rellenar esa colección.