Ajuste de la máquina virtual para Java de IBM

Un servidor de aplicaciones es un servidor basado en Java™ y requiere un entorno de JVM (máquina virtual Java) para ejecutarse y dar soporte a aplicaciones de empresa que se ejecutan en el mismo. Como parte de la configuración del servidor de aplicaciones puede configurar el entorno de ejecución de Java SE para ajustar el rendimiento y el uso de los recursos del sistema. Este tema se aplica a las máquinas virtuales para Java de IBM®.

Antes de empezar

Nota: En este tema se hace referencia a uno o más de los archivos de registro del servidor de aplicaciones. Como alternativa recomendada, puede configurar el servidor para utilizar la infraestructura de registro y rastreo HPEL en lugar de utilizar los archivos SystemOut.log , SystemErr.log, trace.log y activity.log en sistemas distribuidos y de IBM i. Puede también utilizar HPEL junto con sus recursos de registro nativos de z/OS. Si utiliza HPEL, puede acceder a toda la información de registro y rastreo utilizando la herramienta de línea de mandatos LogViewer desde el directorio bin de perfil de servidor. Consulte la información sobre la utilización de HPEL para resolver problemas de aplicaciones para obtener más información sobre la utilización de HPEL.
  • Determine el tipo de JVM en la que se ejecuta el servidor de aplicaciones.

    [AIX Solaris HP-UX Linux Windows][z/OS]Emita el mandato java –fullversion desde el directorio raíz_servidor_aplicaciones/java/bin del servidor de aplicaciones.

    [AIX Solaris HP-UX Linux Windows]En respuesta a este mandato, Java graba información sobre la JVM, incluyendo la información del proveedor de la JVM, en la ventana donde ejecuta el mandato; por ejemplo:
    Java versión completa "JRE 1.6.0 IBM Windows 32 compilación pwi3260sr7-20091217_01 (sr7)" 

    [z/OS]En respuesta a este mandato, Java graba información sobre la JVM, incluida la información del proveedor de la JVM, en stderr.

    [IBM i]Emita el mandato dspwasinst desde el directorio raíz_perfil/bin. La salida de este mandato contiene el valor JAVA_HOME y otra información sobre la JVM habilitada para el perfil del servidor de aplicaciones.

    [AIX Solaris HP-UX Linux Windows]Si el servidor de aplicaciones está ejecutándose en una JVM HotSpot de Sun, consulte el tema Ajuste de las máquinas virtuales Java de Sun HotSpot (Solaris y HP-UX).

    [IBM i]Utilice el mandato managesdk, si desea habilitar el perfil de servidor de aplicaciones para que utilice una JVM distinta.

  • [IBM i][AIX Solaris HP-UX Linux Windows]Verifique que:
    1. Está instalada en el sistema la versión más reciente de JVM soportada.
    2. Está instalada en el sistema la actualización del servicio más reciente soportada. Prácticamente, cada nuevo nivel de servicio incluye mejoras de rendimiento de JVM.
  • [z/OS]Verifique que está instalada en el sistema la actualización del servicio más reciente. Prácticamente, cada nuevo nivel de servicio incluye mejoras de rendimiento de JVM.

Acerca de esta tarea

Cada proveedor JVM proporciona información detallada sobre el rendimiento y el ajuste de su JVM. Utilice la información que se proporciona en este tema junto con la información que se proporciona con la JVM que se ejecuta en el sistema.

[z/OS]Tanto el controlador como el sirviente contienen una JVM. La información de este tema sólo se aplica a la JVM del sirviente. Normalmente, no es necesario ajustar la JVM del controlador.

Un Java SE Runtime Environment proporciona el entorno para ejecutar aplicaciones de empresa y servidores de aplicaciones. Por lo tanto, la configuración de Java representa un rol importante en la determinación del rendimiento y el consumo de recursos del sistema para un servidor de aplicaciones y las aplicaciones que se ejecutan en el mismo.

La máquina virtual para Java de IBM Versión 6.0 incluye las últimas especificaciones Java EE (Java Platform, Enterprise Edition) y proporciona mejoras en el rendimiento y la estabilidad sobre las versiones anteriores de Java.

No obstante, aunque el ajuste de la JVM depende del proveedor de JVM que se utilice, existen algunos conceptos generales de ajuste que se aplican a todas las JVM. Estos conceptos generales incluyen:

  • Ajuste del compilador. Todas las JVM utilizan compiladores JIT (Just-In-Time In Time) para compilar códigos de bytes Java en instrucciones nativas durante el tiempo de ejecución.
  • Ajuste del almacenamiento dinámico o de la memoria de Java. El ajuste de la función de gestión de memoria de la JVM o la recogida de basura es un buen punto de partida para mejorar el rendimiento de la JVM.
  • Ajuste de la carga de clases.
  • Optimización del inicio frente al rendimiento de ejecución

Los siguientes pasos facilitan instrucciones específicas sobre cómo realizar los siguientes tipos de ajuste para cada JVM. Estos pasos no tienen que llevarse a cabo en un orden específico.

Procedimiento

  1. [z/OS]Limite el número de vuelcos que se realizan en situaciones específicas.

    En determinadas condiciones de error, es posible que fallen varias hebras de servidor de aplicaciones y la JVM solicita un TDUMP para cada una de esas hebras. Si un número significativo de hebras fallan a la vez, el número resultante de TDUMP que se realizan simultáneamente puede provocar otros problemas del sistema, por ejemplo. Utilice la variable de entorno JAVA_DUMP_OPTS para especificar el número de volcados que desea que la JVM produzca en determinadas situaciones. El valor especificado para esta variable no afecta al número de operaciones TDUMP que se generan debido a las llamadas de com.ibm.jvm.Dump.SystemDump() realizadas desde aplicaciones que se ejecutan en el servidor de aplicaciones.

    Por ejemplo, si desea configurar JVM de modo que:
    • Se limite el número de operaciones TDUMP realizadas a una
    • Se limite el número de operaciones AVADUMP realizadas a un máximo de tres
    • No se capture ninguna documentación si se produce una operación INTERRUPT
    Entonces establezca la variable JAVA_DUMP_OPTS en el siguiente valor:
    JAVA_DUMP_OPTS=ONANYSIGNAL(JAVADUMP[3],SYSDUMP[1]),ONINTERRUPT(NONE) 
  2. Optimice el rendimiento del arranque y del tiempo de ejecución.

    En algunos entornos, es más importante optimizar el rendimiento durante el arranque del servidor de aplicaciones que el rendimiento en tiempo de ejecución. En otros entornos, es más importante optimizar el rendimiento en tiempo de ejecución. De manera predeterminada, las máquinas virtuales para Java de IBMse han optimizado para el rendimiento en tiempo de ejecución, mientras que las JVM basadas en HotSpot se han optimizado para el rendimiento durante el arranque.

    El compilador JIT (Just-in-Time ) de Java afecta a la optimización del rendimiento del arranque o el tiempo de ejecución. El nivel de optimización inicial que el compilador utiliza influye en la cantidad de tiempo necesario para compilar un método de clase y la cantidad de tiempo necesario para en iniciar el servidor. Para que el arranque sea más rápido, reduzca el nivel de optimización inicial que utiliza el compilador. Sin embargo, si se reduce el nivel de optimización inicial, el rendimiento en tiempo de ejecución de las aplicaciones puede verse disminuido debido a que los métodos de clase se compilan ahora en un nivel de optimización reducido.

    • -Xquickstart

      Este valor afecta al modo en que la máquina virtual para Java de IBM utiliza un nivel de optimización reducido para las compilaciones de métodos de clase. Un nivel de optimización más bajo permite un arranque más rápido del servidor, aunque disminuye el rendimiento de la ejecución. Si no se especifica este parámetro, de forma predeterminada, la máquina virtual para Java de IBM arranca con un nivel de optimización inicial alto para las compilaciones, lo que causa un rendimiento de ejecución más rápido a expensas de un arranque más lento del servidor.

      Puede establecer esta propiedad en el panel de la máquina virtual Java mediante la consola administrativa. Para obtener detalles, consulte la información sobre la configuración de la máquina virtual Java.

      Información Valor
      Valor predeterminado Alto nivel inicial de optimización del compilador
      Recomendado Alto nivel inicial de optimización del compilador
      Uso Si especifica -Xquickstart se mejora el tiempo de inicio del servidor.
    [z/OS]Para acelerar la inicialización de JVM y mejorar el tiempo de arranque del servidor, especifique los siguientes argumentos de línea de mandatos en el campo Argumentos generales de JVM en la sección Propiedades generales del separador Configuración.
    -Xquickstart
    -Xverify:none
  3. Configure el tamaño del almacenamiento dinámico.

    Los parámetros del almacenamiento dinámico de Java influyen en el comportamiento de la recogida de basura. El aumento del tamaño del almacenamiento dinámico da soporte a la creación de más objetos. Como un almacenamiento dinámico grande tarda en llenarse, la aplicación tiene más tiempo de ejecución antes de que se produzca la recogida de basura. No obstante, un almacenamiento dinámico grande también precisa de más tiempo para ser compactado, y hace que la recogida de basura dure más.

    La JVM utiliza umbrales definidos para gestionar el almacenamiento que está asignado. Cuando se alcanzan los umbrales, el recopilador de basura se invoca para liberar el almacenamiento no utilizado. Por lo tanto, la recogida de basura puede ocasionar una degradación significativa del rendimiento Java. Antes de modificar los tamaños inicial y máximo del almacenamiento dinámico debe tener en cuenta la siguiente información:
    • En la mayor parte de los casos, debe establecer el tamaño del almacenamiento dinámico de la JVM en un valor superior al tamaño de almacenamiento dinámico de JVM inicial. Esto permite que la JVM funcione con eficacia durante los períodos de estado normal y sin oscilaciones dentro de los confines del almacenamiento dinámico inicial. Este valor también permite que JVM opere con eficacia durante los períodos con un gran volumen de transacciones porque la JVM puede ampliar el almacenamiento dinámico hasta el valor especificado para el tamaño máximo de almacenamiento dinámico de JVM. En algunos casos raros en los que es necesario un rendimiento óptimo, es posible que desee especificar el mismo valor para el tamaño máximo e inicial del almacenamiento dinámico. Este valor elimina la actividad general que se produce cuando la JVM expande o contrae el tamaño del almacenamiento dinámico de JVM. Antes de cambiar alguno de los tamaños de almacenamiento dinámico de JVM, verifique que la asignación de almacenamiento dinámico de JVM sea lo bastante grande para dar cabida al nuevo tamaño de almacenamiento dinámico.
    • No haga que el tamaño del almacenamiento dinámico inicial sea tan grande que aunque al principio mejora el rendimiento demorando la recogida de basura, cuando ésta se produce, el proceso de recogida afecta al tiempo de respuesta porque el proceso tiene que ejecutarse durante más tiempo.

    [z/OS]La información de almacenamiento dinámico de Java está contenida en los registros SMF y se puede visualizar dinámicamente utilizando el mandato de consola DISPLAY,JVMHEAP.

    Para utilizar la consola administrativa para configurar el tamaño del almacenamiento dinámico:

    1. En la consola administrativa, pulse Servidores > Tipos de servidor > WebSphere Application Servers >nombre_servidor.
    2. [AIX Solaris HP-UX Linux Windows][IBM i]En la sección infraestructura del servidor, pulse Java y gestión de procesos > Definición de proceso > Máquina Virtual Java.
    3. [z/OS]En la sección Infraestructura del servidor, pulse Java y gestión de procesos > Definición de proceso.
    4. [z/OS]Seleccione Control o Servant y, a continuación, seleccione Máquina virtual Java.
    5. Especifique un nuevo valor en el campo Tamaño de almacenamiento dinámico inicial o Tamaño máximo de almacenamiento dinámico.

      También puede especificar valores para los dos campos si es necesario ajustar los dos valores.

      Para analizar el rendimiento, los tamaños inicial y máximo del almacenamiento dinámico deben ser iguales.

      El valor del tamaño inicial de almacenamiento dinámico especifica, en megabytes, la cantidad de almacenamiento asignado para el almacenamiento dinámico de JVM cuando la JVM se inicia. El valor del tamaño máximo de almacenamiento dinámico especifica, en megabytes, la cantidad máxima de almacenamiento que se puede asignar al almacenamiento dinámico de JVM. Ambos valores tienen un efecto significativo en el rendimiento.

      Si se ajusta un sistema de producción donde se desconoce el tamaño del conjunto de trabajos de las aplicaciones de empresa que se ejecutan en ese sistema, un valor de inicio adecuado para el tamaño inicial del almacenamiento dinámico es el 25 por ciento del tamaño máximo del almacenamiento dinámico. A continuación, la JVM intenta adaptar el tamaño del almacenamiento dinámico al tamaño del conjunto de trabajos de la aplicación.

      La siguiente ilustración anterior representa tres perfiles de CPU, cada una ejecuta una carga de trabajo fija con distintos valores de almacenamiento dinámico de Java. En el perfil central, los tamaños inicial y máximo del almacenamiento dinámico se establecen en 128 MB. Se producen cuatro recogidas de basura. El tiempo total de la recogida de basura es de alrededor del 15 por ciento del total de la ejecución. Al duplicar los parámetros de almacenamiento dinámico a 256 MB, como en el perfil superior, aumenta la longitud del tiempo de trabajo entre las recogidas de basura. Sólo se producen tres recogidas de basura, pero la duración de las mismas aumenta. En el tercer perfil, el tamaño de almacenamiento dinámico se reduce a 64 MB y muestra el efecto contrario. Con un tamaño de almacenamiento dinámico más pequeño, se reduce el tiempo entre las recogidas de basura, pero éstas tardan menos. Para las tres configuraciones el tiempo total de recogida de basura ha sido de aproximadamente el 15 por ciento. Este ejemplo ilustra un concepto importante sobre el almacenamiento dinámico de Java y su relación con la utilización de objetos. Siempre existe un coste para la recogida de basura al ejecutar aplicaciones de empresa.

      Variación de valores de almacenamiento dinámico de Java

      Ejecute una serie de pruebas que varían los valores del almacenamiento dinámico de Java. Por ejemplo, ejecute experimentos con 128 MB, 192 MB, 256 MB y 320 MB. En cada prueba, supervise el uso total de memoria. Si se amplía el almacenamiento dinámico de forma demasiado agresiva, podría producirse paginación.

      [AIX Solaris HP-UX Linux Windows]Utilice el mandato vmstat o el Monitor de rendimiento de Windows para comprobar la paginación. Si se produce paginación, reduzca el tamaño del almacenamiento dinámico o añada más memoria al sistema.

      [IBM i]Utilice el mandato WRKSYSSTS de IBM i para comprobar la paginación. Si se produce paginación, reduzca el tamaño del almacenamiento dinámico o añada más memoria al sistema.

      [z/OS]Si se produce paginación, reduzca el tamaño del almacenamiento dinámico o añada más memoria al sistema.

      Cuando hayan finalizado todas las ejecuciones, compare las estadísticas siguientes:
      • Número de llamadas a la recogida de basura
      • Promedio de duración de una recogida de basura
      • Proporción entre la duración de una llamada a la recogida de basura y el tiempo medio entre dos llamadas

      Si la aplicación no utiliza objetos de forma abusiva y no tiene pérdidas de memoria, se alcanza el estado de utilización de memoria estable. La recogida de basura también se produce con menos frecuencia y con una duración menor.

      Si el espacio libre del almacenamiento dinámico se establece en 85 por ciento o más, considere la posibilidad de disminuir los valores del tamaño máximo del almacenamiento dinámico, ya que el servidor de aplicaciones y la aplicación están infrautilizando la memoria asignada por el almacenamiento dinámico.

      [z/OS]Si ha configurado los servidores para realizar la ejecución en la modalidad de 64 bits, puede especificar un tamaño máximo de almacenamiento dinámico de la JVM para estos servidores significativamente mayor que el valor predeterminado. Por ejemplo, puede especificar un tamaño máximo inicial del almacenamiento dinámico de 1844 MB para el controlador y el sirviente, si el servidor se ha configurado para ejecutarse en la modalidad 64 bits.

    6. Pulse Aplicar.
    7. Pulse Guardar para guardar los cambios en la configuración maestra.
    8. Pare y reinicie el servidor de aplicaciones.

    También puede utilizar los siguientes parámetros de la línea de mandatos para ajustar estos valores. Estos parámetros se aplican a todas las JVM soportadas y se utilizan para ajustar los tamaños máximo y mínimo del almacenamiento dinámico para cada instancia del servidor o del servidor de aplicaciones.

    • -Xms

      Este parámetro controla el tamaño inicial del almacenamiento dinámico de Java. Si se ajusta este parámetro se reduce la actividad general de recogida de basura y se mejoran la productividad y el tiempo de respuesta del servidor. Para algunas aplicaciones, el valor predeterminado de esta opción puede ser demasiado bajo, lo que causa un número elevado de recogidas de basura sin importancia.

      Información Valor
      Valor predeterminado 50 MB
      Recomendado Específico de la carga de trabajo pero superior al valor por omisión.
      Uso Si se especifica -Xms256m se establece el tamaño inicial del almacenamiento dinámico en 256 MB.
    • -Xmx

      Este parámetro controla el tamaño máximo del almacenamiento dinámico de Java. Al aumentar este parámetro se aumenta la memoria disponible para el servidor de aplicaciones y reduce la frecuencia de la recogida de basura. Al aumentar este valor se puede mejorar la productividad y el tiempo de respuesta del servidor. Sin embargo, al aumentar este valor también se aumenta la duración de la recogida de basura cuando ésta se produce. Este valor nunca debe ser superior al valor de la memoria disponible para la instancia del servidor de aplicaciones. Si se aumenta el valor por encima de la memoria del sistema disponible puede provocar paginación del sistema y una disminución significativa en el rendimiento.

      Información Valor
      Valor predeterminado De forma predeterminada, la JVM calcula dinámicamente el tamaño de almacenamiento dinámico de Java basado en la memoria disponible en el sistema.
      Recomendado Específico de la carga de trabajo, pero superior al valor predeterminado, en función de la cantidad disponible de memoria física.
      Uso Si se especifica -Xmx512m se establece el tamaño máximo del almacenamiento dinámico en 512 MB.
      Avoid trouble Avoid trouble: Especifique un valor para el parámetro -Xmx para reducir los posibles problemas de falta de memoria.gotcha
    • [AIX][Windows][IBM i]-Xlp

      Utilice este parámetro con la máquina virtual para que Java de IBM asigne el almacenamiento dinámico al utilizar las páginas grandes, como las páginas de 16 MB. Antes de especificar este parámetro, verifique que el sistema operativo se haya configurado para dar soporte a páginas grandes. Al utilizar páginas grandes se reduce la actividad general de CPU necesaria para realizar un seguimiento de la memoria del almacenamiento dinámico y permite también crear un almacenamiento dinámico mayor.

      Valor predeterminado
      64 KB si utiliza Java 8
    • [IBM i][AIX]–Xlp64k

      Este parámetro se puede utilizar para asignar el almacenamiento dinámico utilizando las páginas de tamaño mediano, como por ejemplo 64 KB. Con este tamaño de página de memoria virtual para la memoria que una aplicación requiere puede mejorar el rendimiento y la productividad de la aplicación debido a las características de hardware asociadas a un tamaño de página más grande.

      [IBM i][AIX]i5/OS y AIX proporcionan un soporte enriquecido de unos 64 KB porque las páginas de 64 KB están diseñadas para que sean páginas de uso general. Las páginas de 64 KB son fáciles de habilitar y las aplicaciones pueden obtener ventajas en el rendimiento cuando se utilizan páginas de 64 KB. Este valor puede modificarse sin cambiar la configuración del sistema operativo. No obstante, se recomienda ejecutar los servidores de aplicaciones en una agrupación de almacenamiento independiente si se utilizan páginas de 64 KB.

      Recomendado
      Utilice el tamaño de página de 64 KB siempre que sea posible.

      [IBM i]Los sistemas i5/OS POWER5+ y i5/OS Versión 6, Release 1, dan soporte a un tamaño de página de 64 KB.

      [AIX]Los sistemas POWER5+, y AIX 5L Versión 5.3 con el paquete de mantenimiento recomendado 5300-04 da soporte a un nuevo tamaño de página de 64 KB al ejecutar el kernel de 64 bits.

    • [IBM i][AIX]–Xlp4k

      Este parámetro se puede utilizar para asignar el almacenamiento dinámico utilizando páginas de 4 KB. Este tamaño de página de memoria virtual para la memoria que una aplicación requiere, en lugar de 64 KB, puede afectar negativamente el rendimiento y la productividad de la aplicación debido a que algunas funciones del hardware están asociadas a un tamaño de página menor.

      [IBM i][AIX]El valor de asignación de almacenamiento dinámico de Java puede modificarse sin cambiar la configuración del sistema operativo. No obstante, se recomienda ejecutar los servidores de aplicaciones en una agrupación de almacenamiento independiente si se utilizan páginas de 64 KB.

      Recomendado
      Utilice -Xlp64k en lugar de -Xlp4k siempre que sea posible.
  4. Ajuste la memoria Java.
    Las aplicaciones de empresa escritas en lenguaje Java implican complejas relaciones de objetos y utilizan gran número de objetos. Aunque el lenguaje Java gestiona automáticamente la memoria asociada con los ciclos de vida de los objetos, es importante comprender los patrones de uso de la aplicación para objetos. Concretamente, verifique que existan las siguientes condiciones:
    • La aplicación no hace un uso abusivo de objetos
    • La aplicación no pierde objetos
    • Los parámetros de almacenamiento dinámico de Java se han establecido correctamente para manejar el patrón de uso de un objeto concreto.
    1. Compruebe el uso abusivo de objetos.

      [AIX Solaris HP-UX Linux Windows][IBM i]Puede revisar los contadores para el tiempo de ejecución de JVM, que se incluyen en los informes de Tivoli Performance Viewer, para determinar si una aplicación está usando con exceso los objetos. Debe especificar la opción de línea de mandatos -XrunpmiJvmtiProfiler, así como el nivel máximo de módulo JVM, con el fin de habilitar los contadores de la interfaz del perfilador de máquinas virtuales Java, JVMTI.

      [IBM i][AIX Solaris HP-UX Linux Windows]El mejor resultado de tiempo medio entre recogidas de basura es como mínimo de cinco a seis veces la duración media de una recogida de basura. Si no alcanza este número, la aplicación está gastando más del 15 por ciento de su tiempo en la recogida de basura.

      [z/OS]Puede comprobar si la aplicación está haciendo un uso abusivo de objetos, observando los contadores del tiempo de ejecución de JVM. Debe especificar la opción de línea de mandatos -XrunpmiJvmtiProfiler, así como el nivel máximo de módulo JVM, con el fin de habilitar los contadores de la interfaz del perfilador de máquinas virtuales Java, JVMTI. El mejor resultado de tiempo medio entre recogidas de basura es como mínimo de cinco a seis veces la duración media de una recogida de basura. Si no alcanza este número, la aplicación está gastando más del 15 por ciento de su tiempo en la recogida de basura.

      Si la información indica que hay un cuello de botella en la recogida de basura, hay dos formas de eliminarlo. La forma más rentable de optimizar la aplicación es implementar memorias caché y agrupaciones de objetos. Utilice un perfilador de Java para determinar qué objetos serán el objetivo. Si no puede optimizar la aplicación, pruebe la incorporación de memoria, procesadores y clones. La memoria adicional permite a cada clon mantener un tamaño razonable de almacenamiento dinámico. Los procesadores adicionales permiten que los clones se ejecuten en paralelo.

    2. Compruebe si hay pérdidas de memoria.

      Las pérdidas de memoria en el lenguaje Java contribuyen peligrosamente a los cuellos de botella de la recogida de basura. Las pérdidas de memoria son peores que el uso abusivo de memoria, pues una pérdida de memoria, tarde o temprano, lleva a la inestabilidad del sistema. Con el tiempo, la recogida de basura tendrá lugar cada vez con más frecuencia, hasta que se agote el almacenamiento dinámico y se produzca una anomalía en el código Java con una excepción grave de falta de memoria. Las pérdidas de memoria se producen cuando un objeto no utilizado tiene referencias que nunca se liberan. Las pérdidas de memoria se producen normalmente en clases de recogida como Hashtable, porque la tabla tiene siempre una referencia al objeto, incluso después de eliminar las referencias reales.

      Las cargas de trabajo altas suelen hacer que las aplicaciones tengan errores graves inmediatamente después del despliegue en el entorno de producción. Si una aplicación tiene fugas de memoria, una elevada carga de trabajo puede acelerar el aumento de la fuga y provocar anomalías en la asignación de memoria.

      El objetivo de las pruebas de pérdida de memoria es magnificar los números. Las pérdidas de memoria se miden en términos de cantidad de bytes o kilobytes que no puede liberar la recogida de basura. La tarea delicada consiste en diferenciar estas cantidades entre los tamaños esperados de memoria útil y no útil. Esta tarea se logra con mayor facilidad si los números se hacen grandes, consiguiendo así desfases mayores y una identificación más fácil de las inconsistencias. La siguiente lista proporciona información sobre cómo interpretar los resultados de la prueba de pérdida de memoria:
      • Prueba de larga ejecución

        Los problemas de pérdida de memoria se manifiestan sólo después de un determinado período de tiempo, por lo que se detectan fácilmente en pruebas de larga duración. Los test de corta ejecución proporcionan indicaciones no válidas del lugar en que se producen las pérdidas de memoria. A veces es difícil saber cuándo se está produciendo una pérdida de memoria en el lenguaje Java, sobre todo cuando el uso de la memoria parece que aumenta repentinamente o de forma monótona en un período de tiempo dado. La razón por la que es difícil detectar una pérdida de memoria es que estos tipos de aumentos pueden ser válidos o pueden ser el objetivo del desarrollador. Para aprender a distinguir los objetos que no se utilizan en absoluto del uso diferido de objetos, ejecute las aplicaciones durante más tiempo. Las pruebas de aplicaciones que se ejecutan durante más tiempo ofrecen una mayor confianza para saber si se está produciendo realmente dicho retraso en el uso de los objetos.

      • Prueba repetitiva

        En muchos casos, los problemas de pérdida de memoria se produce debido a la repetición sucesiva de la misma prueba. El objetivo de las pruebas de pérdida de memoria es establecer un gran desfase entre la memoria que se utiliza y la que no, en términos de sus tamaños relativos. Mediante la repetición una y otra vez del mismo escenario, el desfase se hace notorio progresivamente. Esta prueba es de gran ayuda si el número de pérdidas provocadas por la ejecución de una prueba concreta es tan pequeña que difícilmente se puede detectar en una sola ejecución.

        Las pruebas repetitivas se pueden utilizar a nivel de sistema o de módulo. La ventaja con las pruebas a nivel de módulo es que se tiene un mejor control. Cuando se diseña un módulo para que mantenga el módulo privado sin crear efectos colaterales externos como el uso de la memoria, las pruebas en busca de pérdidas de memoria son más sencillas. En primer lugar, se registra el uso de la memoria antes de la ejecución del módulo. A continuación, se ejecuta un conjunto de pruebas fijas de forma repetitiva. Al final de la ejecución de las pruebas, se registra el uso de la memoria actual y se comprueba si hay cambios significativos. Hay que tener presente que debe sugerirse la recogida de basura cuando se registra el uso real de la memoria, mediante la inserción de System.gc() en el módulo donde desea realizar la recogida de basura o mediante el uso de una herramienta de perfiles que fuerce el suceso.

      • Prueba de simultaneidad

        Algunos problemas de pérdida de memoria pueden producirse sólo cuando hay en ejecución varias hebras de la aplicación. Desgraciadamente, los puntos de sincronización son muy susceptibles a las pérdidas de memoria, ya que añaden complicación a la lógica del programa. Una programación hecha a la ligera puede dar lugar a referencias mantenidas o no liberadas. La incidencia de las pérdidas de memoria se suele facilitar o acelerar aumentando la simultaneidad en el sistema. La forma más común de aumentar la simultaneidad es aumentar el número de clientes del controlador de prueba.

        A la hora de decidir las pruebas a utilizar para la detección de pérdidas de memoria, tenga en cuenta los siguientes puntos:
        • Una buena prueba trabaja sobre áreas de la aplicación en la que se crean objetos. En la mayoría de los casos, es necesario conocer la aplicación. Una descripción del escenario puede sugerir la creación de espacios de datos, como añadir un registro nuevo, crear una sesión HTTP, realizar una transacción o buscar un registro.
        • Revisar las áreas en que se utiliza la recogida de objetos. Por lo general, las pérdidas de memoria se componen de objetos dentro de la misma clase. Además, las clases de recogida como Vector y Hashtable (tabla de totales de control) son lugares comunes en los que las referencias a objetos se almacenan de forma implícita, mediante la invocación a los métodos de inserción correspondientes. Por ejemplo, el método get (obtener) de un objeto Hashtable no elimina su referencia al objeto recuperado.

      [AIX Solaris HP-UX Linux Windows][IBM i]También puede utilizar Tivoli Performance Viewer como ayuda para buscar pérdidas de memoria.

      [IBM i][AIX Solaris HP-UX Linux Windows]Para obtener los mejores resultados, repita los experimentos aumentando la duración, por ejemplo, solicitudes de 1.000, 2.000 y 4.000 páginas. El gráfico de Tivoli Performance Viewer de memoria no utilizada tiene una forma dentada. Cada punto bajo del gráfico corresponde a una recogida de basura. Habrá una pérdida de memoria si alguna de las siguientes condiciones aparece en el gráfico:
      • La cantidad de memoria utiliza justo tras cada recogida de basura aumenta de forma significativa. Cuando se da esta condición, el patrón dentado se parece más a una escalera.
      • El patrón dentado tiene una forma irregular.
      • La diferencia entre el número de objetos asignados y el número de objetos liberados aumenta con el tiempo.

      Si el consumo del almacenamiento dinámico que indica una posible pérdida durante periodos en los que el servidor de aplicaciones está constantemente cerca del 100% de utilización de la CPU), pero desaparece cuando la carga de trabajo es menor o durante periodos de inactividad, se trata de un caso de fragmentación del almacenamiento dinámico. La fragmentación del almacenamiento dinámico se puede producir cuando la JVM puede liberar objetos suficientes para satisfacer las solicitudes de asignación de memoria durante los ciclos de recogida de basura, pero la JVM no tiene tiempo para compactar las pequeñas áreas de memoria libres en el almacenamiento dinámico para formar áreas contiguas mayores.

      Otra forma de fragmentación del almacenamiento dinámico se produce cuando se liberan objetos menores de 512 bytes. Los objetos se liberan, pero el almacenamiento no se recupera, lo que provoca la fragmentación de la memoria hasta que se produce una compactación del almacenamiento dinámico.

      La fragmentación del almacenamiento dinámico puede reducirse forzando la compactación. No obstante, hay una penalización de rendimiento cuando se fuerza la compactación. Utilice el mandato Java -X para ver la lista de opciones de memoria.

  5. Ajuste la recogida de basura

    [z/OS]La JVM utiliza un recopilador de basura paralelo para explotar al máximo el SMP durante la mayoría de los ciclos de recogida de basura.

    El estudio de la recogida de basura de Java permite conocer cómo está utilizando la memoria la aplicación. La recogida de basura es muy importante en Java. Al eliminar la carga de la gestión de memoria del escritor de aplicaciones, las aplicaciones Java son más sólidas que las escritas en lenguajes que no proporcionan recogida de basuras. Esta solidez se aplica siempre que la aplicación no haga un uso abusivo de los objetos. La recogida de basura normalmente consume del 5 al 20 por ciento del tiempo de ejecución total de una aplicación que funcione adecuadamente. Si no se gestiona, la recogida de basura constituye uno de los mayores cuellos de botella de una aplicación.

    Si supervisa la recogida de basura mientras se ejecuta una carga de trabajo fija tendrá más información de si la aplicación está utilizando objetos. La recogida de basura puede detectar incluso la presencia de pérdidas de memoria.

    Puede utilizar los valores de la JVM para configurar el tipo y el comportamiento de la recogida de basura. Cuando la JVM no puede asignar un objeto del almacenamiento dinámico actual debido a la falta de espacio contiguo, se invoca el recopilador de basura para que reclame memoria de los objetos Java que ya no se utilizan. Cada proveedor de JVM suministra políticas de colector de basura y parámetros de ajuste exclusivos.

    Puede utilizar el valor Recogida de basura verbosa en la consola administrativa para habilitar la supervisión de la recogida de basura. La salida de este valor incluye las estadísticas de la recogida de basura de clases. El formato del informe generado no está estandarizado entre las diferentes JVM o niveles de release.

    Para ajustar los valores de recogida de basura de JVM:

    1. En la consola administrativa, pulse Servidores > Tipos de servidor > WebSphere Application Servers >nombre_servidor.
    2. [AIX Solaris HP-UX Linux Windows][IBM i]En la sección Infraestructura del servidor, pulse Java y gestión de procesos > Definición de proceso > Máquina virtual Java
    3. [AIX Solaris HP-UX Linux Windows][IBM i]Entre la opción –X que desea cambiar en el campo Argumentos de JVM genéricos.
    4. [z/OS]En la sección Infraestructura del servidor, pulse Java y gestión de procesos > Definición de procesos > Sirviente.
    5. [z/OS]En Propiedades adicionales, pulse Propiedades personalizadas.
    6. [z/OS]Añada o actualice la entrada de entorno para IBM_JAVA_OPTIONS de la manera siguiente.
      1. Si observa una entrada de entorno existente denominada IBM_JAVA_OPTIONS, edítela para añadir la opción de Java –x Java que desea añadir al valor existente.
      2. De lo contrario, pulse Nueva para crear una entrada de entorno nueva. Rellene los siguientes valores en sus respectivos campos del formulario:
        Información Valor
        Nombre: IBM_JAVA_OPTIONS
        Valor: La opción –X de Java que desea añadir
        Descripción: Una descripción de dicha opción

      [z/OS]Este procedimiento actualiza el archivo was.env en el directorio de configuración de WebSphereApplication Server. El cambio se aplicará a los valores para todas las regiones de servant, control y complemento.

    7. Pulse Aplicar.
    8. Pulse Guardar para guardar los cambios en la configuración maestra.
    9. Pare y reinicie el servidor de aplicaciones.

    En la lista siguiente, se describen las opciones –X para los distintos recopiladores de basura de la JVM.

    El recopilador de basura de la máquina virtual para Java de IBM.
    En la publicación IBM SDK, Java Technology Edition, Version 8 User Guide se proporciona una guía completa para la implementación de IBM del colector de basura Java.

    Utilice la opción Java -X para ver una lista de opciones de memoria.

    • -Xgcpolicy
      La máquina virtual para Java de IBM proporciona cuatro políticas para la recogida de basura. Cada política proporciona ventajas únicas.
      Nota: Mientras que cada política proporciona ventajas únicas, para la versión 8 de WebSphere Application Server, gencon es el valor predeterminado de la política de recogida de basura. Las versiones anteriores del servidor de aplicaciones especifican que el valor optthruput es el valor predeterminado de la política de recogida de basura.
      • gencon es la política predeterminada. Esta política funciona con el recopilador de basura generacional. El esquema generacional trata de alcanzar un alto rendimiento junto con periodos de pausa de recogida de basura reducidos. Para alcanzar este objetivo, el almacenamiento dinámico se divide entre segmentos nuevos y antiguos. Los objetos de larga duración se promocionan al espacio antiguo mientras que los objetos de corta duración se recogen rápidamente en el colector de basura en el nuevo espacio. La política gencon proporciona ventajas significativas para muchas aplicaciones. No obstante, no es adecuada para todas las aplicaciones y normalmente es más difícil de ajustar.
      • optthruput proporciona un alto rendimiento con periodos de pausa de recogida de basura. Durante una recopilación de basura, todas las hebras de aplicación se detienen para la marca, el barrido y la compactación, cuando ésta es necesaria. La política gencon es suficiente para la mayoría de las aplicaciones.
      • optavgpause es la política que reduce el periodo de pausa de recogida de basura realizando las fases de marca y barrido de la recogida de basura mientras se ejecuta una aplicación. Esta política provoca un pequeño impacto en el rendimiento general.
      • subpool es una política que aumenta el rendimiento en sistemas de varios procesadores que habitualmente utilizan más de 8 procesadores. Esta política sólo está disponible en procesadores IBM System i System p y System z. La política subpool es parecida a la política gencon excepto en que el almacenamiento dinámico se divide en subagrupaciones que proporcionan una escalabilidad mejorada para la asignación de objetos.
      Información Valor
      Valor predeterminado gencon
      Recomendado gencon
      Uso Si se especifica Xgcpolicy:gencon se establece la política de recogida de basura en gencon.

      Si establece gcpolicy en gencon se inhabilita la marca concurrente. Debe obtener los mejores resultados en cuanto al rendimiento cuando utiliza la política gencon, salvo que los tiempos de respuesta de aplicaciones sean erráticos, lo que es una indicación de que puede experimentar problemas de tiempos de pausa

      Si establece gcpolicy en optavgpause se habilita la marca concurrente con sus valores predeterminados. Este valor soluciona los tiempos de respuesta erráticos de las aplicaciones ocasionados por la recogida de basura normal. No obstante, esta opción puede disminuir el rendimiento general.

    • -Xnoclassgc

      De forma predeterminada, la JVM descarga una clase de la memoria cuando no quedan instancias activas de dicha clase. La sobrecarga de cargar y descargar la misma clase varias veces puede disminuir el rendimiento.

      Avoid trouble Avoid trouble: Puede utilizar -Xnoclassgc para inhabilitar la recogida de basura de clases. No obstante, el impacto sobre el rendimiento de la recogida de basura de clases normalmente es mínimo y si se desactiva la recogida de basura de clases en un sistema basado en Java EE (Java Platform, Enterprise Edition), con su uso masivo de cargadores de clases de aplicaciones, podría crear de forma efectiva una pérdida de memoria de datos de clase y causar que la JVM generara una excepción de falta de memoria.

      Si utiliza esta opción, cuando vuelva a desplegar una aplicación, siempre deberá reiniciar el servidor de aplicaciones para borrar las clases y los datos estáticos de la versión anterior de la aplicación.

      gotcha
      Información Valor
      Valor predeterminado La recogida de basura de clases está habilitada.
      Recomendado

      No inhabilite la recogida de basura de clases.

      Uso Especifique Xnoclassgc para inhabilitar la recogida de basura de clases.
  6. Habilitar almacenamiento en caché del nombre del localhost De forma predeterminada, en IBM SDK para Java, el método estático java/net/InetAddress.getLocalHost no almacena en memoria el resultado. Este método se utiliza en todo WebSphere Application Server, pero especialmente en los agentes administrativos como el gestor de despliegue y el agente de nodo. Si la dirección de sistema principal local de un proceso no va a cambiar mientras se esté ejecutando, se recomienda utilizar una memoria caché incorporada para la búsqueda de localhost estableciendo la propiedad del sistema com.ibm.cacheLocalHost en el valor true. Consulte el tema de propiedades personalizadas de la máquina virtual Java en el Information Center para encontrar instrucciones sobre cómo definir las propiedades personalizadas en los diversos tipos de procesos.
    Avoid trouble Avoid trouble: La dirección para los servidores configurados mediante DHCP cambia a lo largo del tiempo. No establezca esta propiedad a menos que utilice direcciones IP asignadas de forma estática para su servidor. gotcha
    Información Valor
    Valor predeterminado com.ibm.cacheLocalHost = false
    Recomendado com.ibm.cacheLocalHost = true (ver descripción)
    Uso Si se especifica -Dcom.ibm.cacheLocalHost=true se habilita la memoria caché getLocalHost
  7. Habilite la compartición de clases en una antememoria.

    La opción de compartir clases le permite compartir clases en la memoria caché. Al compartir clases en una memoria caché se mejora el tiempo de arranque y se disminuye el uso de la memoria. Procesos como, por ejemplo, los servidores de aplicaciones, los agentes de nodos y los gestores de despliegue pueden utilizar la opción de compartir clases.

    [IBM i]Esta opción está habilitada, de forma predeterminada, en el servidor de aplicaciones. Para borrar la memoria caché, llame al programa de utilidad app_server_root/bin/clearClassCache o detenga el servidor de aplicaciones y, a continuación, reinicie el servidor de aplicaciones.

    [z/OS][AIX Solaris HP-UX Linux Windows]Si utiliza esta opción, debe borrar la memoria caché cuando no se utiliza el proceso. Para borrar la memoria caché, llame al programa de utilidadraíz_servidor_aplic/bin/clearClassCache.bat/sh o detenga el proceso y, a continuación, reinícielo.

    Nota: Cuando se utiliza clearclasscache, debe detener todas las máquinas virtuales Java asociadas para borrar la memoria caché completa.

    Si es necesario inhabilitar la opción para compartir clases para un proceso, especifique el argumento genérico de la JVM -Xshareclasses:none para ese proceso:

    1. En la consola administrativa, pulse Servidores > Tipos de servidor > WebSphere Application Servers >nombre_servidor.
    2. [AIX Solaris HP-UX Linux Windows][IBM i]En la sección Infraestructura del servidor, pulse Java y gestión de procesos > Definición de proceso > Máquina virtual Java
    3. [z/OS]En la sección Infraestructura del servidor, pulse Java y gestión de procesos > Definición de proceso
    4. [z/OS]Seleccione Control o Servant y, a continuación, seleccione Máquina virtual Java.
    5. Escriba -Xshareclasses:none en el campo Argumentos de JVM genéricos.
    6. Pulse OK (Aceptar).
    7. Pulse Guardar para guardar los cambios en la configuración maestra.
    8. Pare y reinicie el servidor de aplicaciones.
    Información Valor
    Valor predeterminado La opción de compartir clases en una memoria caché está habilitada.
    Recomendado Deje habilitada la opción de compartir clases en una antememoria.
    Uso Si especifica -Xshareclasses:none inhabilita la opción de compartir clases en una opción de memoria caché.
  8. [AIX Solaris HP-UX Linux Windows][z/OS]Habilite las referencias comprimidas en entornos de 64 bits.

    [z/OS][AIX Solaris HP-UX Linux Windows]Puede habilitar las referencias comprimidas en entornos de 64 bits como, por ejemplo, AIX 64, Linux PPC 64, zLinux 64 y Microsoft Windows AMD64, Linux AMD64.

    [IBM i]También puede habilitar las referencias comprimidas en entornos de 64 de IBM i como, por ejemplo, IBM i Versión 6.1.

    La opción de referencias comprimidas de la implementación de IBM del JRE (Java SE Runtime Environment) Versión 6.0 de 64 bits permite limitar todas las referencias de la memoria a un tamaño de 32 bits. En general, las JVM de 64 bits utilizan más espacio de almacenamiento dinámico que las JVM de 32 bits porque utilizan referencias de memoria amplia de 64 bits para direccionar memoria. El almacenamiento dinámico que es direccionable por la referencia de 64 bits es órdenes de magnitud mayor que el almacenamiento dinámico de 32 bits, pero en el mundo real, un almacenamiento dinámico que requiere todos los 64 bits para el direccionamiento normalmente no es necesario. Si se comprimen las referencias se reducirá el tamaño de las direcciones y hará más eficiente el uso del almacenamiento dinámico. Si se comprimen estas referencias también se mejora la memoria caché del procesador y la utilización del bus, y de este modo se mejora el rendimiento.

    Avoid trouble Avoid trouble: gotcha
    La característica de referencias comprimidas no recibe soporte en:
    • JVM de 64 bits de HP-UX
    • JVM de 64 bits de iSeries Classic
    [z/OS]Para habilitar una JVM de 64 bits para que se ejecuten en la modalidad de referencias comprimidas, tiene que especificar una nueva variable de entorno en la configuración de WebSphere Application Server. En la consola administrativa:
    1. Pulse: Servidores>Tipos de servidor> WebSphere Application Servers>nombre_servidor.
    2. Pulse el separador Configuración. En Infraestructura de servidor, pulse Java y gestión de proceso > Definición de proceso > servant.
    3. En Propiedades adicionales, pulse Propiedades personalizadas.
      Añada o actualice la entrada de entorno para IBM_JAVA_OPTIONS de la manera siguiente:
      1. Si ve una entrada de entorno existente denominada IBM_JAVA_OPTIONS, edítela para añadir la opción de Java –Xcompressedrefs al valor existente.
      2. De lo contrario, pulse Nueva para crear una entrada de entorno nueva. Rellene los valores siguientes en los campos respectivos con el formato:
        Información Valor
        Nombre: IBM_JAVA_OPTIONS
        Valor: -Xcompressedrefs
        Descripción: Habilite la modalidad de referencias comprimidas de 64 bits
    [z/OS]Este procedimiento actualiza el archivo was.env en el directorio de configuración de WebSphereApplication Server. El cambio se aplicará a los valores para todas las regiones de servant, control y complemento.
    Avoid trouble Avoid trouble: Cuando se proporciona Xcompressedrefs como argumento JVM genérico, WebSphere Application Server no podrá iniciarse debido a un error de opción Java no soportada. Si la aplicación requiere más de un almacenamiento dinámico Java de 30 GB, debe utilizarse la modalidad predeterminada de 64 bits.gotcha

    De manera predeterminada, el producto habilita automáticamente la compresión de puntero en las plataformas soportadas si el tamaño del almacenamiento dinámico (controlado por el parámetro -Xmx) se establece bajo un determinado tamaño de almacenamiento dinámico (unos 25 GB, según la plataforma), si no, tomará el valor predeterminado de las referencias no comprimidas. El usuario puede alterar temporalmente estos valores predeterminados utilizando las siguientes opciones de línea de mandatos.

    [z/OS]Nota: WebSphere Application Server para z/OS no habilita automáticamente la compresión de puntero. Se recomienda a los usuarios habilitar manualmente la compresión de puntero utilizando las opciones de línea de comandos.
    Nota: Para Java 8 SR2 FP10 o z/OS Java 8 SR3, la opción -Xcompressedrefs se habilita de forma predeterminada hasta 57GB y puede utilizarse con valores superiores en función de la plataforma.
    Las siguientes opciones de línea de mandatos controlan la característica de referencias comprimidas:
    -Xcompressedrefs
    Esta opción de línea de mandatos habilita la característica de referencias comprimidas. Cuando la JVM se inicia con esta opción de línea de mandatos utilizará referencias de memoria amplia de 32 bits completas para ocuparse del almacenamiento dinámico. Esta característica se puede utilizar hasta un determinado tamaño de almacenamiento dinámico (unos 29 GB, en función de la plataforma) controlado por el parámetro -Xmx.
    -Xnocompressedrefs
    Estas opciones de línea de mandatos inhabilitan la característica de referencias comprimidas. Cuando la JVM se inicia con esta opción de línea de mandatos utilizará referencias de memoria amplia de 64 bits completas para ocuparse del almacenamiento dinámico. Esta opción la puede utilizar el usuario para alterar temporalmente la habilitación predeterminada de la compresión de puntero, si es necesario.
  9. Ajuste el proceso de actualización de configuración para la configuración de una célula grande.
    En una configuración de células grande, es posible que necesite determinar si es más importante el rendimiento de la actualización de la configuración o la comprobación de coherencia. El gestor de despliegue mantiene un repositorio de configuración maestro de toda la célula. De forma predeterminada, cuando cambia la configuración, el producto compara la configuración del espacio de trabajo con el repositorio maestro para mantener la coherencia del espacio de trabajo. Sin embargo, el proceso de verificación de la coherencia puede provocar un aumento en la cantidad de tiempo para guardar un cambio de configuración o para desplegar un gran número de aplicaciones. Los factores siguientes influyen en la cantidad de tiempo necesaria:
    • Cuantos más servidores de aplicaciones o clústeres se hayan definido en la célula, más tiempo se tarda en guardar un cambio de configuración.
    • Cuantas más aplicaciones se hayan desplegado en una célula, más tiempo se tarda en guardar un cambio de configuración.
    Si el período de tiempo necesario para cambiar un cambio de configuración no es satisfactorio, puede añadir la propiedad personalizada config_consistency_check a los valores de la JVM y establecer el valor de esta propiedad en false.
    1. En la consola administrativa, pulse Administración del sistema > Gestor de despliegue.
    2. A continuación, bajo Infraestructura del servidor, pulse Java y gestión de procesos y luego pulse Definición de procesos.
    3. En Propiedades adicionales, pulse Máquina virtual Java > Propiedades personalizadas > Nueva.
    4. Escriba config_consistency_check en el campo de nombre y false en el campo de valor.
    5. Pulse Aceptar y, a continuación, guarde dichos cambios en la configuración maestra.
    6. Reinicie el servidor.
    Supported configurations Supported configurations: La propiedad personalizada config_consistency_check sólo afecta al proceso del gestor de despliegue. No afecta a otros procesos, incluyendo los procesos del agente de nodo y del servidor de aplicaciones. La comprobación de coherencia no se realiza en estos procesos. No obstante, en los archivos SystemOut.log para dichos procesos, es posible que vea una nota de que la comprobación de coherencia esté inhabilitada. Para dichos procesos que no son del gestor de despliegue, puede ignorar este mensaje.sptcfg

    Si está utilizando el mandato wsadmin wsadmin -conntype none en la modalidad local, debe establecer la propiedad config_consistency_check en false antes de emitir este mandato.

Qué hacer a continuación

Siga recopilando y analizando datos a medida que vaya ajustando cambios hasta que esté satisfecho con el rendimiento de la JVM.

Icon that indicates the type of topic Task topic



Timestamp icon Last updated: last_date
http://www14.software.ibm.com/webapp/wsbroker/redirect?version=cord&product=was-nd-mp&topic=tprf_tunejvm_v61
File name: tprf_tunejvm_v61.html