2010-09-29 16 views
36

¿Es posible hacer un balanceo de los registros del recolector de basura en Sun JVM?Registros del recolector de basura rodante en java

Actualmente tengo generar registros usando:

-XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -verbose:gc -Xloggc:gc.log 

Pero tengo que girar manualmente usando una cola FIFO y rotatelogs para crear un nuevo registro para cada día. Espero que haya una mejor solución para esto.

Tal vez haya una forma de acceder a estas entradas de registro desde dentro de java para poder redirigirlas a log4j?

Editar: la solución con cola FIFO no es lo suficientemente bueno, porque si el proceso que lee desde esta cola (por ejemplo rotatelogs) lee a reducir la velocidad se ralentizará todo el JVM (aparentemente Sun/Oracle hace el registro de GC de forma sincrónica)

+0

Su solución me parece muy buena; ¿Qué no te gusta de eso? Tiene colocation: la rotación ocurre cerca de su invocación de Java (que configura el registro) en lugar de en el código de la aplicación (que debe ser ajeno al registro). –

+0

También mi instinto diría que no, que no es posible o que si es posible, sería a través de una API privada y restringida que probablemente no desee forzar en su aplicación. –

+0

-XX: + PrintGCDateStamps no se aplica a java5? –

Respuesta

77

El soporte integrado para la rotación de registro de GC se ha agregado a HotSpot JVM. Se describe en la RFE 6941923 y está disponible en:

Hay tres indicadores JVM nuevas que se puede usar para habilitarlo y configurarlo:

  • -XX:+UseGCLogFileRotation
    se debe utilizar con -Xloggc:<filename>;
  • -XX:NumberOfGCLogFiles=<number of files>
    debe ser> = 1, el valor predeterminado es uno;
  • -XX:GCLogFileSize=<number>M (or K)
    por defecto se configurará en 512K.
+5

-XX: NumberOfGClogFiles debe tener una L mayúscula (-XX: NumberOfGCLogFiles) –

+0

Es una pena que esto no sea por día, no veo un punto en el tamaño de un rollo, generalmente quiero ver los registros de un día determinado, no el 123MB :) –

+2

El punto en el balanceo del tamaño es que el tamaño total de los archivos de registro está restringido (a NumberOfGCLogFiles * GCLogFileSize), lo que evita errores sin espacio en el dispositivo y supera el inconveniente de encontrar los registros de un día determinado . – vboerchers

3

¿Has probado estas nuevas opciones?

me trataron jdk7u7, jdk7u6 y jdk6u35 así:

java -Xloggc:gc.log -XX:+PrintGCDetails -XX:+UseGCLogRotation -XX:NumberOfGClogFiles=3 -XX:GCLogFileSize=10M 

pero con todas las versiones que estoy viendo este error:

Error: Could not create the Java Virtual Machine. 
Error: A fatal exception has occurred. Program will exit. 

Solución de error # 6941923 para 7u2 se hace referencia aquí: http://www.oracle.com/technetwork/java/javase/2col/7u2bugfixes-1394661.html

+1

Su bandera está equivocada - es "-XX: + UseGCLogFileRotation" (le falta el "Archivo" en la bandera) – Ryan

+1

Y falta la "L" mayúscula en "-XX: NumberOfGClogFiles" (como estaba originalmente en mi respuesta) –

+0

No es culpa de Blazej, los errores tipográficos se encuentran en la documentación de errores a la que hizo referencia (http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6941923). – t0r0X

5

Si no puede actualizar su versión de java para usar las nuevas banderas para rotar el registro de gc, entonces podría especificar un archivo de gc diferente cada vez que se inicie la aplicación s:

JAVA_OPTS="-Xms1024m -Xmx1024m -XX:MaxPermSize=256m -verbose:gc -XX:+PrintGCTimeStamps -XX:+PrintGCDetails -Xloggc:/path/to/log/dir/gc.log-"`date +%Y-%m-%d-%H-%M` 

Cuando se hace referencia a la setenv, normalmente durante el arranque o parada, se hará referencia a un archivo de registro diferente. En Unix esto se puede utilizar como un método para 'rotar' el registro.

+0

Un mejor método sería agregar la salida detallada a un archivo y rotar este archivo con logrotate o similar. Obtienes registros más largos y no se descomponen en un lío de archivos diferentes. –

+2

@Pathduck Esta respuesta es para versiones antiguas de Java. Significa que no puedes agregar a Xlogcc. Mis experimentos también muestran que no se puede hacer que la java en ejecución se cierre y vuelva a abrir el registro. Tampoco puede hacer que busque (EOF), java recuerda la posición del archivo dentro de Xloggc. Mayor PITA. – kubanczyk

+0

@Pathduck No todos los sistemas tienen logrotate desafortunadamente. Esta solución publicada para administradores que tienen que prescindir. Agregar la fecha de esta manera también es útil para rotar catalina.out :-) – Underverse

1

Un enfoque interesante sería redirigir gc.ingrese a una tubería con nombre -Xloggc:/my/named/pipe How to write GC log to named pipe

leyó entonces la forma que la tubería de la propia aplicación: How to open a Windows named pipe from Java?

e ingrese a una arbitraria (por ejemplo asíncrono de laminación) logger logback a partir del código.

Probé eso en una máquina con Windows. Desafortunadamente, es más complicado configurar Windows que Linux.

En Windows funciona básicamente con la ayuda de un Powershell script adicional (también puede ser una aplicación dedicada). Este sample project también contiene una aplicación de demostración que se puede utilizar de inmediato para probar la redirección de registros de GC a Logback a través de SLF4J.

+0

Según tengo entendido, debe tener un consumidor escuchando la tubería con nombre o eventualmente bloqueará. –

+0

Sí, así es el proyecto de script. También contiene una "válvula" para el caso en que nada recibe los mensajes y un par de comentarios que describen eso. –

+0

Aunque es intrigante, significa que su aplicación ahora depende de que este componente externo funcione correctamente. Esto probablemente significaría para nosotros que no podríamos usarlo en producción: -/ –

Cuestiones relacionadas