La primera cosa sobre CMS que he aprendido es que necesita más memoria que los otros colectores, alrededor de 25 a 50% más es un buen punto de partida. Esto le ayuda a evitar la fragmentación, ya que CMS no hace ninguna compactación como la parada que los coleccionistas del mundo harían. Segundo, haz cosas que ayuden al recolector de basura; Integer.valueOf en lugar de nuevo Integer, elimine las clases anónimas, asegúrese de que las clases internas no accedan a cosas inaccesibles (privadas en la clase externa) cosas así. Cuanto menos basura, mejor. FindBugs y no ignorar las advertencias ayudarán mucho con esto.
En cuanto a afinación, he encontrado que hay que probar varias cosas:
-XX: + UseConcMarkSweepGC
Le dice JVM utilizar CMS en titular gen.
Arregle el tamaño de su pila: -Xmx2048m -Xms2048m Esto evita que GC tenga que hacer cosas como crecer y reducir el montón.
-XX: + UseParNewGC
uso paralelo en lugar de recogida de serie en la generación joven. Esto acelerará tus colecciones menores, especialmente si tienes configurado un gen joven muy grande. Una gran generación joven generalmente es buena, pero no va más de la mitad del tamaño de la vieja generación.
-XX: ParallelCMSThreads = X
establecer el número de hilos que CMS utilizará cuando se está haciendo las cosas que se pueden hacer en paralelo.
-XX: + CMSParallelRemarkEnabled observación es de serie de forma predeterminada, esto puede acelerar.
-XX: + CMSIncrementalMode permite a la aplicación ejecutarse más por pasuing GC entre fases
-XX: + CMSIncrementalPacing permite JVM a la figura cambio la frecuencia con que se acumula con el tiempo
-XX: CMSIncrementalDutyCycleMin = X Minimm cantidad de tiempo empleado en GC
-XX: CMSIncrementalDutyCycle = X empezar por hacer esto GC% del tiempo
-XX: CMSIncrementalSafetyFactor = X
He encontrado que puede obtener tiempos de pausa generalmente bajos si lo configura de manera que básicamente siempre se esté recopilando. Como la mayor parte del trabajo se realiza en paralelo, terminas con pausas predecibles básicamente regulares.
-XX: CMSFullGCsBeforeCompaction = 1
Éste es muy importante. Le dice al recopilador de CMS que siempre complete la colección antes de que comience una nueva. Sin esto, puede encontrarse con la situación en la que arroja un montón de trabajo y comienza de nuevo.
-XX: + CMSClassUnloadingEnabled
Por defecto, CMS le permitirá a sus PermGen crecen hasta que mata a su aplicación de unas pocas semanas a partir de ahora. Esto detiene eso. Sin embargo, su PermGen solo crecerá si utiliza Reflection, o está haciendo un mal uso de String.intern, o está haciendo algo malo con un cargador de clases, o algunas otras cosas.
La relación de supervivencia y la fijación de la duración del reloj también pueden reproducirse, dependiendo de si tiene objetos de vida larga o corta, y de la cantidad de objetos copiados entre los espacios de sobrevivientes con los que puede vivir. Si sabe que todos sus objetos se van a quedar, puede configurar espacios de supervivencia de tamaño cero, y todo lo que sobreviva a una colección de jóvenes se mantendrá de inmediato.
¿De verdad ha experimentado un fallo de modo concurrente? – Justin
Lo hice, honestamente, con bastante frecuencia. p.ej. 295285.052: [GC 295285.052: [ParNew: 197658K-> 197658K (245760K), 0.0000290 segundos] 295285.052: [CMS295286.188: [CMS-concurrent-mark: 3.109/3.348 segundos] [Tiempos: usuario = 6.12 sys = 0.88, real = 3,35 segundos] (error de modo simultáneo): 936976K-> 904898K (962560K), 5,3725960 segundos] 1161866072K-> 926615760K (1237319680K), [CMS Perm: 97908K-> 97897K (131072K)], 5,3729920 segundos] [Tiempos: usuario = 5,36 sys = 0,00, real = 5,37 segundos]. A veces, OOM es bastante rápido y es asesinado, a veces sufre un largo período de GC (la última vez fue más de 10 horas). – jimx
¿Ha agregado algunas configuraciones de gc cuando ejecuta Java? En caso afirmativo, ¿cuáles son esas? – Inv3r53