español - garbage collector java example
¿Cuál es la frecuencia de la recolección de basura en Java? (5)
Página 6 del documento Administración de memoria en la máquina virtual Java HotSpot ™ contiene los siguientes párrafos:
Las recolecciones de generaciones jóvenes ocurren con relativa frecuencia y son eficientes y rápidas porque el espacio de generación joven suele ser pequeño y es probable que contenga muchos objetos que ya no se mencionan.
Los objetos que sobreviven a cierto número de colecciones de generaciones jóvenes eventualmente son promovidos, o mantenidos, a la generación anterior. Ver Figura 1. Esta generación es típicamente más grande que la generación joven y su ocupación crece más lentamente. Como resultado, las colecciones de la generación anterior son poco frecuentes, pero toman mucho más tiempo para completar
¿Podría alguien definir qué significa " frecuente " e " infrecuente " en las declaraciones anteriores? ¿Estamos hablando microsegundos, milisegundos, minutos, días ?
Como es, los términos "frecuente", "infrecuente" son relativos. Y los tiempos no son, de hecho, fijos. Depende del sistema en cuestión. Depende de muchas cosas como:
- Su tamaño de pila y configuración para diferentes partes del montón (gen jóven, viejo, perm gen)
- Comportamiento de la memoria de su aplicación. ¿Cuántos objetos crea y qué tan rápido? ¿Por cuánto tiempo se hace referencia a esos objetos, etc.?
Si su aplicación es monstruo come la memoria, gc se ejecutará como si se ejecutara por su vida. Si su aplicación no demanda demasiada memoria, entonces gc se ejecutará a intervalos decididos por la cantidad de memoria que tenga.
Debido a que la especificación dice "con relativa frecuencia" e infrecuente (con respecto a la generación joven), no podemos estimar la frecuencia en unidades absolutas, como microsegundos, milisegundos, minutos o días.
Es un término relativo. Las colecciones jóvenes pueden ser de varios segundos hasta algunas horas. Las colecciones de generaciones anteriores pueden ser cada pocos segundos, hasta por día. Debería esperar tener muchas más colecciones jóvenes que antiguas colecciones en la mayoría de los sistemas.
Es muy poco probable que sea muchos días. Si el GC ocurre con demasiada frecuencia, por ejemplo, << 100 ms aparte, obtienes un OutOfMemoryError: GC Overhead Exceeded
ya que el JVM previene que eso ocurra.
No es posible dar una respuesta definitiva a esto. Realmente depende de muchos factores, incluida la plataforma (versión de JVM, configuración, etc.), la aplicación y la carga de trabajo.
En un extremo, es posible que una aplicación nunca active un recolector de basura. Podría simplemente sentarse sin hacer nada, o podría realizar un cálculo extremadamente largo en el que no se crean objetos después de la inicialización de la JVM y el inicio de la aplicación.
En el otro extremo, teóricamente es posible que un contenedor de basura termine y otro que comience en pocos nanosegundos . Por ejemplo, esto podría suceder si su aplicación está en las últimas etapas de muerte de un montón completo, o si está asignando matrices patológicamente grandes.
Asi que:
¿Estamos hablando microsegundos, milisegundos, minutos, días?
Posiblemente todo lo anterior, aunque los primeros dos definitivamente serían preocupantes si los observaras en la práctica.
Una aplicación con buen comportamiento no debe ejecutar el GC con demasiada frecuencia. Si su aplicación está desencadenando una colección de espacio joven más de una o dos veces por segundo, esto podría ocasionar problemas de rendimiento. Y las colecciones "completas" demasiado frecuentes son peores porque su impacto es mayor. Sin embargo, es ciertamente plausible que una aplicación mal diseñada / implementada se comporte así.
También está el problema de que el intervalo entre las carreras de GC no siempre es significativo. Por ejemplo, algunos de los GC HotSpot en realidad tienen subprocesos GC ejecutándose en paralelo con los subprocesos de aplicación normales. Si tiene suficientes núcleos, suficiente memoria RAM y suficiente ancho de banda de bus de memoria, un GC paralelo en ejecución constante puede no afectar de forma apreciable el rendimiento de la aplicación (hasta cierto punto).
TL DL: "Frecuente" e "infrecuente" son términos relativos que dependen de la tasa de asignación de memoria y el tamaño del montón. Si desea una respuesta precisa, debe medirla usted mismo para su aplicación particular.
Digamos que su aplicación tiene dos modos, el modo 1 asigna memoria y hace cálculos y el modo 2 permanece inactivo.
Si la asignación de modo 1 es menor que el montón disponible, no es necesario que ocurra un gc hasta que finalice. Tal vez utilizó tan poca memoria RAM que podría hacer una segunda ronda de mode-1 sin colección. Sin embargo, eventualmente se acabará el montón libre, y jvm realizará una colección "poco frecuente".
Sin embargo, si la asignación de modo 1 es una fracción significativa de, o mayor, que el montón de la generación joven, la recolección sería más "frecuente". Durante la colección de gen jóvenes, las asignaciones que sobreviven (imagine que se necesitan datos a través de toda la operación de modo 1), serán promovidas a la vieja generación, dando al joven genio más espacio. La asignación y recolección de jóvenes ahora puede continuar. Eventualmente, el montón de la vieja generación se agotaría, y debe ser recolectado, por lo tanto, "con poca frecuencia".
Entonces, ¿qué tan frecuente es frecuente? Depende de la tasa de asignación y el tamaño del montón. Si jvm choca con el límite del montón a menudo, se acumulará con frecuencia. Si hay mucho montón (digamos 100GB), entonces jvm no necesita recolectar durante mucho tiempo. El inconveniente es que cuando finalmente hace una colección, puede llevar mucho tiempo liberar 100 GB, deteniendo el jvm durante muchos segundos (¡o minutos!). Las JVM actuales son más inteligentes que eso y ocasionalmente forzarían una recopilación (preferiblemente en modo-2). Y con coleccionistas paralelos, podría suceder todo el tiempo si fuera necesario.
En última instancia, la frecuencia depende de la tarea y el montón, así como de cómo se configuran varios parámetros de vm. Si desea una respuesta precisa, debe medirlos usted mismo para su aplicación particular.