yugioh forzar example español como collector java garbage-collection

forzar - garbage collector java example



¿Cómo forzar la recolección de basura en Java? (21)

¿Es posible forzar la recolección de basura en Java, incluso si es difícil de hacer? Sé sobre System.gc(); y Runtime.gc(); Pero solo sugieren hacer GC. ¿Cómo puedo forzar GC?


Realmente, no te entiendo. Pero para ser claro acerca de "Creación de Objetos Infinitos", quise decir que hay un código en mi gran sistema para crear objetos que se manejan y están vivos en la memoria, no pude obtener este código en realidad, ¡solo un gesto!

Esto es correcto, solo gesto. Usted tiene prácticamente las respuestas estándar ya dadas por varios carteles. Tomemos esto uno por uno:

  1. No pude conseguir este pedazo de código en realidad

Correcto, no hay un JVM real, tal es solo una especificación, un montón de informática que describe un comportamiento deseado ... Hace poco cavé en la inicialización de objetos Java desde código nativo. Para obtener lo que desea, la única forma es hacer lo que se denomina anulación agresiva. Los errores si se hacen mal son tan malos que si se hacen mal, debemos limitarnos al alcance original de la pregunta:

  1. algún trozo de código en mi gran sistema hace creación de objetos

La mayoría de los carteles aquí supondrán que está diciendo que está trabajando en una interfaz, si es así, tendríamos que ver si se le entrega todo el objeto o un artículo a la vez.

Si ya no necesita un objeto, puede asignar nulo al objeto, pero si lo hace mal, se genera una excepción de puntero nulo. Apuesto a que puedes lograr un mejor trabajo si usas NIO.

Cada vez que usted o yo o alguien más recibe: " Por favor, lo necesito horriblemente " . Es casi un precursor universal de la destrucción casi total de aquello en lo que está tratando de trabajar ... escríbanos un pequeño código de muestra, limpiándolo todo. Código actual utilizado y nos muestran su pregunta.

No te sientas frustrado. A menudo, lo que se resuelve es que su dba está utilizando un paquete comprado en algún lugar y el diseño original no está ajustado para estructuras de datos masivos.

Eso es muy común.



(Lo siento, no puedo agregar esto como un comentario ya que no tengo suficientes puntos de reputación).

Una vez me entrevisté en una empresa de procesamiento de imágenes para un trabajo en Java (aunque no tenía mucha experiencia en Java).

Su historia de angustia que me interesaba, era que su programa asignaría un GRAN búfer para la imagen. Una vez, terminaron con la imagen y la memoria, la deferieron. Sabiendo que realmente necesitaban recuperar la memoria más temprano que tarde, intentaron usar una llamada explícita a Java gc () durante un momento de silencio del programa. Desafortunadamente, gc () es simplemente una sugerencia para el tiempo de ejecución de Java y no tuvo ningún efecto.

Según recuerdo, terminaron teniendo que reciclar la memoria ellos mismos.


.gc es un candidato para la eliminación en futuras versiones. Un ingeniero de Sun comentó una vez que tal vez menos de veinte personas en el mundo realmente saben cómo usar .gc (). Anoche trabajé un poco durante algunas horas en una central / crítica. la estructura de datos utilizando datos generados por SecureRandom, en algún lugar justo después de los 40,000 objetos, vm se ralentizaría como si se hubiera quedado sin punteros. Claramente se estaba asfixiando con tablas de punteros de 16 bits y mostraba el clásico comportamiento de "maquinaria defectuosa".

Intenté -Xms y así sucesivamente, seguí girando un poco hasta que se ejecutara a aproximadamente 57, xxx algo. Luego se ejecutaría gc pasando de, por ejemplo, 57,127 a 57,128 después de un gc (), a un ritmo similar al de la expansión de códigos en el campamento Easy Money.

Su diseño necesita reparaciones fundamentales, probablemente un enfoque de ventana deslizante.


El siguiente código se toma del método assertGC (...). Intenta forzar al recolector de basura no determinista a recolectar.

List<byte[]> alloc = new ArrayList<byte[]>(); int size = 100000; for (int i = 0; i < 50; i++) { if (ref.get() == null) { // Test succeeded! Week referenced object has been cleared by gc. return; } try { System.gc(); } catch (OutOfMemoryError error) { // OK } try { System.runFinalization(); } catch (OutOfMemoryError error) { // OK } // Approach the jvm maximal allocatable memory threshold try { // Allocates memory. alloc.add(new byte[size]); // The amount of allocated memory is increased for the next iteration. size = (int)(((double)size) * 1.3); } catch (OutOfMemoryError error) { // The amount of allocated memory is decreased for the next iteration. size = size / 2; } try { if (i % 3 == 0) Thread.sleep(321); } catch (InterruptedException t) { // ignore } } // Test failed! // Free resources required for testing alloc = null; // Try to find out who holds the reference. String str = null; try { str = findRefsFromRoot(ref.get(), rootsHint); } catch (Exception e) { throw new AssertionFailedErrorException(e); } catch (OutOfMemoryError err) { // OK } fail(text + ":/n" + str);

Fuente (agregué algunos comentarios para mayor claridad): Ejemplo de NbTestCase


En la documentación de OutOfMemoryError , declara que no se lanzará a menos que la VM no haya podido recuperar la memoria luego de una recolección de basura completa. Por lo tanto, si continúa asignando memoria hasta que reciba el error, ya habrá forzado una recolección de basura completa.

Presumiblemente, la pregunta que realmente quería hacer era "¿cómo puedo recuperar la memoria que creo que debería recuperar con la recolección de basura?"


Hay alguna forma indirecta para forzar el recolector de basura. Solo debe llenar el montón con objetos temporales hasta el punto en que se ejecutará el recolector de basura. He hecho una clase que obliga al recolector de basura de esta manera:

class GarbageCollectorManager { private static boolean collectionWasForced; private static int refCounter = 0; public GarbageCollectorManager() { refCounter++; } @Override protected void finalize() { try { collectionWasForced = true; refCounter--; super.finalize(); } catch (Throwable ex) { Logger.getLogger(GarbageCollectorManager.class.getName()).log(Level.SEVERE, null, ex); } } public int forceGarbageCollection() { final int TEMPORARY_ARRAY_SIZE_FOR_GC = 200_000; int iterationsUntilCollected = 0; collectionWasForced = false; if (refCounter < 2) new GarbageCollectorManager(); while (!collectionWasForced) { iterationsUntilCollected++; int[] arr = new int[TEMPORARY_ARRAY_SIZE_FOR_GC]; arr = null; } return iterationsUntilCollected; } }

Uso:

GarbageCollectorManager manager = new GarbageCollectorManager(); int iterationsUntilGcExecuted = manager.forceGarbageCollection();

No sé cuánto es útil este método, ya que llena el montón constantemente, pero si tiene una aplicación de misión crítica que DEBE forzar el GC, cuando esta sea la forma portátil de Java de forzar el GC.



La especificación de JVM no dice nada específico sobre la recolección de basura. Debido a esto, los proveedores son libres de implementar GC en su camino.

Así que esta vaguedad causa incertidumbre en el comportamiento de la recolección de basura. Debe consultar los detalles de su JVM para conocer los enfoques / algoritmos de recolección de basura. También hay opciones para personalizar el comportamiento también.


La mejor manera (si no solo) de forzar un GC sería escribir una JVM personalizada. Creo que los recolectores de basura son conectables, por lo que probablemente podría elegir una de las implementaciones disponibles y modificarla.

Nota: Esta NO es una respuesta fácil.


Me gustaría añadir algo aquí. Tenga en cuenta que Java se ejecuta en una máquina virtual y no en una máquina real. La máquina virtual tiene su propia forma de comunicación con la máquina. Puede oscilar de un sistema a otro. Ahora, cuando llamamos al GC, le pedimos a la máquina virtual de Java que llame al recolector de basura.

Dado que el recolector de basura está en una máquina virtual, no podemos forzarlo a que realice una limpieza en ese momento. Más bien que hacemos cola nuestra solicitud con el recolector de basura. Depende de la máquina virtual, después de un tiempo determinado (esto puede cambiar de un sistema a otro, generalmente cuando la memoria de umbral asignada a la JVM está llena) la máquina real liberará espacio. :RE


Otra opción es no crear nuevos objetos.

La agrupación de objetos está lejos para reducir la necesidad de GC en Java.

La agrupación de objetos generalmente no será más rápida que la creación de objetos (especialmente para objetos livianos), pero es más rápida que la recolección de basura. Si creaste 10.000 objetos y cada objeto tenía 16 bytes. Eso es 160.000 bytes que GC tiene que reclamar. Por otro lado, si no necesita los 10,000 al mismo tiempo, puede crear un grupo para reciclar / reutilizar los objetos, lo que elimina la necesidad de construir nuevos objetos y elimina la necesidad de objetos antiguos de GC.

Algo como esto (no probado). Y si desea que sea seguro para subprocesos, puede intercambiar el LinkedList por un ConcurrentLinkedQueue.

public abstract class Pool<T> { private int mApproximateSize; private LinkedList<T> mPool = new LinkedList<>(); public Pool(int approximateSize) { mApproximateSize = approximateSize; } public T attain() { T item = mPool.poll(); if (item == null) { item = newInstance(); } return item; } public void release(T item) { int approxSize = mPool.size(); // not guaranteed accurate if (approxSize < mApproximateSize) { recycle(item); mPool.add(item); } else if (approxSize > mApproximateSize) { decommission(mPool.poll()); } } public abstract T newInstance(); public abstract void recycle(T item); public void decommission(T item) { } }


Para solicitar manualmente GC (no de System.gc ()):

  1. Ir a: carpeta bin en JDK, por ejemplo, C: / Archivos de programa / Java / jdk1.6.0_31 / bin
  2. Abrir jconsole.exe
  3. Conéctese al proceso local deseado.
  4. Vaya a la pestaña de memoria y haga clic en realizar GC.

Para tu información

El método llamado System.runFinalizersOnExit (verdadero) garantiza que se llame a los métodos finalizadores antes de que Java se apague. Sin embargo, este método es intrínsecamente inseguro y ha quedado en desuso. Una alternativa es agregar "ganchos de apagado" con el método Runtime.addShutdownHook.

Masarrat siddiqui


Sería mejor si describiera la razón por la que necesita la recolección de basura. Si está utilizando SWT, puede disponer recursos como Image y Font para liberar memoria. Por ejemplo:

Image img = new Image(Display.getDefault(), 16, 16); img.dispose();

También hay herramientas para determinar los recursos no disueltos.


Si necesita forzar la recolección de basura, quizás debería considerar cómo está administrando los recursos. ¿Estás creando objetos grandes que persisten en la memoria? ¿Está creando objetos grandes (por ejemplo, clases de gráficos) que tienen una interfaz Disposable y no llama a dispose() cuando termina con ella? ¿Está declarando algo a nivel de clase que solo necesita dentro de un solo método?


Si se está quedando sin memoria y obtiene una OutOfMemoryException , puede intentar aumentar la cantidad de espacio de almacenamiento disponible para Java iniciando su programa con java -Xms128m -Xmx512m lugar de solo java . Esto le dará un tamaño de pila inicial de 128Mb y un máximo de 512Mb, que es mucho más que el estándar de 32Mb / 128Mb.


Su mejor opción es llamar a System.gc() que simplemente es una sugerencia para el recolector de basura que desea que haga una colección. Sin embargo, no hay forma de forzar y de recolectar de inmediato ya que el recolector de basura no es determinista.



Use Runtime.getRuntime().gc() o use el método de utilidad System.gc()


, es casi posible que tenga que llamar a métodos en el mismo orden y, al mismo tiempo, estos son:

System.gc (); System.runFinalization ();

incluso si solo hay un objeto para limpiar el uso de estos dos métodos al mismo tiempo, obligue al recolector de basura a usar el método finalise() del objeto inalcanzable liberando la memoria asignada y haciendo lo que indica el método finalize() .

SIN EMBARGO , es una práctica terrible utilizar el recolector de basura porque su uso podría introducir una sobrecarga en el software que puede ser incluso peor que en la memoria, el recolector de basura tiene su propio hilo que no es posible controlar más dependiendo de El algoritmo utilizado por gc podría llevar más tiempo y, por lo tanto, es muy ineficiente. Debería verificar su software si es peor con la ayuda de gc, ya que definitivamente está roto, una buena solución no debe depender de gc.

NOTA: solo para tener en cuenta esto funcionará solo si en el método de finalización no es una reasignación del objeto, si esto sucede, el objeto se mantendrá vivo y tendrá una resurrección que es técnicamente posible.