Para una aplicación que genera mucha basura de corta vida y nada duradero, un enfoque que puede funcionar es un gran montón con casi todo el gen y casi todo lo que sobrevive a una colección YG más de una vez.
Por ejemplo (digamos que usted tenía una JVM de 32 bits)
- 3072M montón (XMS y XmnI)
- 128M titular (es decir,2944m XMN)
- MaxTenuringThreshold = 1
- SurvivorRatio = 190 (es decir, cada espacio sobreviviente es 1/192 de la YG)
- TargetSurvivorRatio = 90 (es decir, llenar esos supervivientes tanto como sea posible)
Los parámetros exactos que usaría para esta configuración dependen de cuál sea el tamaño de estado estable de su conjunto de trabajo (es decir, cuánto está vivo en el momento de cada colección). El pensamiento aquí obviamente va en contra de las reglas normales de tamaño de montón, pero entonces no tienes una aplicación que se comporte de esa manera. La idea es que la aplicación es principalmente basura de corta duración y un poco de datos estáticos, por lo tanto, configure el jvm para que los datos estáticos se conserven rápidamente y luego tenga un YG lo suficientemente grande para que no se recopile v a menudo minimizando la frecuencia de las pausas. Tendría que girar las perillas repetidas veces para determinar qué tamaño es bueno para usted & cómo se equilibra con el tamaño de la pausa que recibe por colección. Es posible que encuentre pausas YG más cortas pero más frecuentes, por ejemplo.
No dice cuánto tiempo se ejecuta su aplicación, pero el objetivo aquí es no tener colecciones permanentes durante la vida de la aplicación. Esto puede ser imposible, por supuesto, pero vale la pena apuntar.
Sin embargo, no es solo el problema de la colección lo que es importante en su caso, es donde se asigna la memoria. El recopilador NUMA (solo compatible con el colector de rendimiento y activado con el conmutador UseNUMA) hace uso de la observación de que un objeto a menudo se utiliza exclusivamente por el hilo que lo creó &, por lo que asigna memoria en consecuencia. No estoy seguro de en qué se basa en Linux pero usa MPO (optimización de ubicación de memoria) en Solaris, some details on one of the GC guys blogs
Dado que está utilizando 64bit jvm, asegúrese de estar utilizando también CompressedOops.
Teniendo en cuenta la tasa de asignación de objetos (posiblemente algún tipo de lib de ciencia) y la duración de la vida, entonces debe prestar cierta atención a la reutilización de objetos. Un ejemplo de un lib hacer esto es la javalution StackContext
Por último vale la pena señalar que las pausas GC no son la única STW hace una pausa, usted podría funcionar con la versión 6u21 early access que tiene algunas correcciones a los interruptores PrintGCApplicationStoppedTime y PrintGCApplicationConcurrentTime (que efectivamente impresión tiempo en un punto seguro global y tiempo entre esos puntos de seguridad). Puede usar el indicador tracesafepointstatistics para hacerse una idea de lo que está causando que necesite un punto de seguridad (es decir, ningún subproceso está ejecutando código byte).
Si la generación joven es grande, ¿no significaría eso que los objetos con vidas semi-largas desaparecen en recolecciones baratas de generaciones jóvenes, dándole menos recolecciones costosas de la vieja generación? – gustafc
@elec: No puedo ayudarlo aquí ... Pero su pregunta es sintomática de un problema fundamental con Java y su administración de memoria "automatizada" (vea cómo está automatizada ahora uh). Cuanto más utilizo Java (hace diez años), más me gustaría poder administrar la memoria yo mismo (y, sí, he trabajado con lenguajes que obligan a la gestión manual de la memoria, incluidos los lenguajes de segunda generación [que entran directamente en códigos hexadecimales], hace décadas). ¿Cuánto desperdicio de energía y tiempo en el mundo de Java tratando de entender y "afinar" ese GC no determinista? Para lo que no debería ser un problema: me da ganas de volver a C++. – SyntaxT3rr0r
@WizardOfOdds - Estoy de acuerdo contigo ... aunque me gusta Java, parece que esta no es la herramienta adecuada para usar en un entorno en el que se requieren latencias muy bajas. – Eleco