java - 2gb - optifine jvm arguments
¿Cuál es la diferencia entre ParallelGC y ParallelOldGC? (5)
Bueno, después de mucha búsqueda e investigación, lo que he llegado a entender es el siguiente:
-XX: + UseParallelGC : esto permite que GC use múltiples subprocesos en la generación Joven, pero para la generación anterior / actual todavía se utilizan los algoritmos de Marca de serie y Compacto .
-XX: + UseParallelOldGC : esto le permite al GC usar la marca paralela y el algoritmo compacto en la generación anterior / permanente .
Entendamos
El algoritmo y la disposición de la memoria, como marcar y copiar, intercambiar espacios, que funciona en la generación Joven no funciona para la generación anterior por muchos motivos
Baja mortalidad: en la generación anterior, la "tasa de mortalidad" es significativamente más baja que la de la generación joven. En una aplicación Java típica, la mayoría de los objetos mueren rápidamente y pocos viven más tiempo. Como los objetos que sobreviven en la generación joven y promovidos a la generación anterior, se observa que estos objetos tienden a vivir una vida más larga. Lo que conduce a una tasa de mortalidad muy inferior en la generación anterior en comparación con la generación joven.
Significativamente tamaño: la generación anterior es significativamente más grande que la generación joven. Debido a que la generación joven se aclara rápidamente, hay relativamente poco espacio disponible para los muchos objetos de corta duración (pequeña generación joven). En la Vieja Generación, los objetos se acumulan con el tiempo. Por lo tanto, debe haber mucho más espacio en una generación anterior que en la generación joven (generación antigua grande)
Poca asignación: en la generación anterior ocurre menos asignación que en la generación joven. Esto se debe a que, en la generación anterior, los objetos solo surgen cuando el recolector de basura promueve los objetos supervivientes de la generación joven a la antigua. En la Generación Joven, por otro lado, todos los objetos que la aplicación genera con nuevos, es decir, la mayoría de las asignaciones, ocurren en la Generación Joven.
Teniendo en cuenta estas diferencias , se ha elegido un algoritmo para la generación joven que terminará la recolección de basura tan pronto como sea posible, ya que se debe llamar a menudo debido a la alta tasa de mortalidad [punto (1)]. Además, el algoritmo debe garantizar que la asignación de memoria posible más eficiente [punto (3)] sea posible porque se asigna mucho en la generación joven. El algoritmo de marcar y copiar en la generación joven tiene estas propiedades.
Por otro lado , este algoritmo no tiene sentido en la Vieja Generación. La situación es diferente: el recolector de basura tiene que cuidar muchos objetos en la Antigua Generación [punto (2)] y la mayoría de ellos aún están vivos; solo una pequeña parte se ha vuelto inalcanzable y se puede liberar [punto (1)]. Si el recolector de basura copiara todos los objetos sobrevivientes en cada recolección de basura, tal como lo hace con la marca y copia, entonces pasaría mucho tiempo copiándolo sin ganar mucho.
Por lo tanto , el algoritmo de marcar y barrer se realiza en la generación anterior, donde no se copia nada, sino que simplemente se liberan los objetos inalcanzables. Dado que este algoritmo conduce a la fragmentación del montón, se ha considerado adicionalmente una variación del algoritmo de marca y barrido, en el cual, después de la fase de barrido, se realiza una compactación, por lo que se reduce la fragmentación . Este algoritmo se llama un algoritmo de marca y compacta .
Una marca y un algoritmo compacto pueden consumir mucho tiempo, ya que es necesario recorrer el gráfico de objetos en las siguientes etapas.
- Calificación.
- Cálculo de nuevas ubicaciones.
- Ajustes de referencia.
- Emocionante
En el cálculo de la nueva fase de ubicación , cada vez que obtiene un espacio libre, intenta encontrar un objeto que pueda moverse a este espacio ( desfragmentación ). Almacena el par para su uso en fases posteriores. Esto hace que el algoritmo consuma más tiempo.
Aunque marcar y comparar resuelve algunos problemas específicos de la generación de tenencia, tiene un problema grave, ya que se trata de un evento STW (Stop the world) que consume mucho tiempo y puede afectar seriamente la aplicación.
Algoritmos alternativos para la vieja generación.
Para reducir los tiempos de descanso, se han considerado alternativas al algoritmo de marcado y compacto en serie:
Un algoritmo paralelo de marca y compacta que aún encierra todos los subprocesos de la aplicación, pero luego maneja el etiquetado y la subsiguiente compactación con varios subprocesos del recolector de basura. Si bien esto sigue siendo un enfoque de parada en el mundo, la pausa resultante es más corta en una máquina con varios núcleos o multiprocesadores que el algoritmo de marcado y compacta en serie. Este algoritmo paralelo en la generación anterior (llamado "ParallelOld") ha estado disponible desde Java 5 Update 6 y se selecciona con la opción -XX: + UseParallelOldGC .
Un algoritmo competitivo de marca y barrido que al menos parcialmente compite con la aplicación sin detener sus subprocesos y, en ocasiones, necesita fases cortas para detener el mundo. Este algoritmo de marcado y barrido concurrente (llamado "CMS") ha existido desde Java 1.4.1; se enciende con la opción -XX: + UseConcMarkSweepGC. Es importante destacar que esto es sólo un algoritmo de marca y barrido; La compactación no tiene lugar, lo que lleva al problema de fragmentación ya discutido.
Así que, en pocas palabras, -XX: + UseParallelOldGC se usa como una indicación para usar varios subprocesos mientras se realiza una recopilación importante utilizando el algoritmo Mark y Compact . Si se usa en su lugar, las colecciones menor o joven son paralelas, pero las colecciones principales aún son de un solo hilo.
Espero que esto responda.
Tengo algunas preguntas sobre el algoritmo de GC: Primero, cuando usamos los parámetros como UseSerialGC, UseParallelGC, UseParallelOldGC, etc., especificamos un algoritmo de GC. Cada uno de ellos puede hacer GC en todas las generaciones, ¿verdad?
Por ejemplo, si uso "java -XX: + UseSerialGC", toda la generación usará GC en serie como el algoritmo de GC.
Segundo, ¿puedo usar ParallelGC en Old Gneneration y usar SerialGC en yong generation?
El último como título, ¿cuál es la diferencia entre ParallelGC y ParallelOldGC?
De documentos de Oracle Java SE 8:
https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/collectors.html
El recolector paralelo (también conocido como el recolector de rendimiento) realiza colecciones secundarias en paralelo, lo que puede reducir significativamente la sobrecarga de recolección de basura. Está diseñado para aplicaciones con conjuntos de datos de tamaño mediano a grande que se ejecutan en hardware multiprocesador o multiprocesador. El colector paralelo se selecciona de forma predeterminada en ciertas configuraciones de hardware y sistema operativo, o se puede habilitar explícitamente con la opción -XX: + UseParallelGC.
La compactación paralela es una característica que permite al colector paralelo realizar colecciones principales en paralelo. Sin la compactación paralela, las principales colecciones se realizan utilizando un solo hilo, que puede limitar significativamente la escalabilidad. La compactación paralela se habilita de forma predeterminada si se ha especificado la opción -XX: + UseParallelGC. La opción para apagarlo es -XX: -UseParallelOldGC.
Por lo tanto, si especifica -XX: + UseParallelGC, de forma predeterminada, la recopilación principal también se realizará utilizando varios subprocesos. Lo contrario también es cierto, es decir, si especifica -XX: + UseParallelOldGC, las colecciones secundarias también se realizarán utilizando varios subprocesos.
Echa un vistazo a las opciones de HotSpot VM :
-XX: + UseParallelGC = Usa la recolección de basura paralela para barridos. (Introducido en 1.4.1).
-XX: + UseParallelOldGC = Use la recolección de basura paralela para las colecciones completas. Habilitar esta opción establece automáticamente -XX: + UseParallelGC. (Introducido en 5.0 actualización 6.)
donde Scavenges = GC generación joven.
Esas son dos políticas de gc aplicadas a diferentes regiones de un montón de Java, a saber, las generaciones Nuevas y Antiguas. Aquí hay un enlace que ayuda a aclarar qué opciones implican otras. Es útil, especialmente al comenzar a entender lo que está obteniendo cuando especifica, por ejemplo, ParallelOldGC o ParNewGC. http://www.fasterj.com/articles/oraclecollectors1.shtml
Para responder a su pregunta, debemos comprender un algoritmo diferente. JVM proporciona cuatro recolecciones de basura.
- El recolector de basura serial
- El colector de rendimiento
- El coleccionista de CMS
- El coleccionista g1
El colector en serie se habilita mediante el uso del indicador -XX: + UseSerialGC (aunque normalmente es el valor predeterminado en aquellos casos en los que se puede usar).
El recolector de basura en serie es el recolector predeterminado si la aplicación se ejecuta en una máquina de clase cliente (JVM de 32 bits en Windows o en máquinas con un solo procesador). El recolector en serie usa un solo hilo para procesar el montón. Detendrá todos los subprocesos de la aplicación a medida que se procesa el montón (para un GC menor o completo). Durante un GC completo, compactará completamente la vieja generación.
UseParallelGC, UseParallelOldGC es parte del recolector de rendimiento que es el predeterminado para máquinas Unix con múltiples CPU y cualquier JVM de 64 bits.
El recolector de rendimiento utiliza varios subprocesos para recopilar la generación joven, lo que hace que los GC menores sean mucho más rápidos que cuando se usa el recopilador en serie. El recolector de rendimiento también puede utilizar varios subprocesos para procesar la generación anterior. Ese es el comportamiento predeterminado en JDK 7u4 y versiones posteriores, y ese comportamiento puede habilitarse en JVM JDK 7 anteriores especificando el indicador -XX: + UseParallelOldGC. Debido a que utiliza varios subprocesos, el recolector de rendimiento a menudo se llama el recolector paralelo.
Como es el valor predeterminado en la mayoría de las situaciones en las que se usaría, no es necesario habilitarlo explícitamente . Para habilitarlo donde sea necesario, use las banderas -XX: + UseParallelGC -XX: + UseParallelOldGC
--Pinaki