Tidbits de Matt # 84 – Opciones de JVM, explicadas | de Matthew Groves | Octubre de 2020

La última vez escribí sobre algunas pruebas unitarias fallidas extrañas. Esta semana me gustaría explicar algunas de las opciones de JVM que podría utilizar.

Mientras trataba de averiguar qué causaba que fallaran estas pruebas unitarias, encontré una forma útil de averiguar cuáles son sus configuraciones de memoria de Android Studio:

Esto abrirá un editor de texto donde no solo podrá ver, sino también cambiar algunas de estas configuraciones. Mis configuraciones IDE se enumeran a continuación:

-Xms512m
-Xmx4g
-XX:ReservedCodeCacheSize=240m
-XX:+UseCompressedOops
-Dfile.encoding=UTF-8
-XX:+UseConcMarkSweepGC
-XX:SoftRefLRUPolicyMSPerMB=50
-Dsun.io.useCanonCaches=false
-Djava.net.preferIPv4Stack=true
-Djdk.http.auth.tunneling.disabledSchemes=""
-Djna.nosys=true
-Djna.boot.library.path=

-da
-Xverify:none

-XX:ErrorFile=$USER_HOME/java_error_in_studio_%p.log
-XX:HeapDumpPath=$USER_HOME/java_error_in_studio.hprof
-XX:MaxPermSize=2g

Probablemente hayas visto algunos de ellos, pero ¿qué están haciendo? Miremos más de cerca.

  • -Xms512 m – el tamaño inicial del montón de Java – en este caso 512 MB – aumentar este valor (por una razón razonable) significa que su programa puede funcionar mejor porque inicialmente asigna más memoria. La desventaja es que siempre usa al menos la misma cantidad de memoria, así que configúrelo con cuidado.
  • Xmx4g: tamaño máximo de almacenamiento dinámico de Java: lo configuré en 4 GB (la configuración predeterminada para Android Studio es 1280 MB): si le sobra RAM, aumentar este valor a al menos 2 o 4 GB puede ayudar en gran medida a mejorar el rendimiento: será menos probable que se encuentre OutOfMemoryError
    Nota: he visto algunos enlaces a la configuración org.gradle.jvmargs propiedad en gradle.properties archivo es la cantidad definida Xmx + 1024 m.
  • -XX: ReservedCodeCacheSize =240 m – cantidad máxima de memoria para la compilación de código JIT de Java – aumentar esto (dentro de límites razonables) puede ayudar al rendimiento, especialmente si su aplicación apunta a Java 8.
  • -XX:+UseCompressedOops – Esta bandera especial permite a la JVM comprimir «Punteros a objetos ordinarios» en computadoras de 64 bits, por lo que usan menos memoria (porque probablemente no use todos los 18.5 Exabytes o RAM direccionable). Esto está habilitado de forma predeterminada y probablemente no debería cambiarlo a menos que realmente sepa lo que está haciendo.
  • -Dfile.encoding =UTF-8: establece la codificación predeterminada para leer / escribir archivos.
  • -XX:+UseConcMarkSweepGC – especifica que se debe utilizar el algoritmo «Recogida de garbace de barrido de marcas simultáneas». Hay otras opciones y dependiendo de su configuración puede tener un mejor rendimiento de manera diferente. Sin embargo, generalmente se acepta que los algoritmos más nuevos (G1) son más eficientes ConcMarkSweepGC estaba desactualizado. Este artículo hace un buen trabajo al explicar las diferencias.
  • -XX: SoftRefLRUPolicyMSPerMB =50: esto determina cuánto tiempo (en milisegundos) permanecen activos los valores de referencia suave después de que ya no se hace referencia a ellos. Este artículo explica bien cómo funciona. Sin embargo, todo es cuestión de equilibrio: establecerlo en el valor más bajo posible puede reducir el rendimiento, ya que a menudo tendrá que volver a crear los objetos de uso frecuente.
  • -Dsun.io.useCanonCaches =falso: desactiva el almacenamiento en caché de archivos canónicos en la JVM. La caché de archivos canónica elimina las referencias de los enlaces simbólicos y mejora el tiempo de acceso a los archivos (y, por lo tanto, el tiempo de inicio de la JVM), pero como con cualquier caché, problemas conocidos con el hecho de que se volvió obsoleto y devolvió información incorrecta. En muchos lugares, he visto recomendaciones para desactivarlo de forma predeterminada.
  • -Djava.net.preferIPv4Stack =verdadero: indica a la JVM que utilice IPv4 en lugar de IPv6. encontré artículos afirma que esto evitará el problema de rendimiento que podría encontrar si toda su red no es IPv6 (lo cual es muy probable en 2020).
  • -Djdk.http.auth.tunneling.disabledSchemes =”” – A partir de Java 8, los proxies web que utilizaron la autenticación básica para tunelizar a través de HTTPS fallarán de forma predeterminada.. Puede anular este cambio (y permitir que estas solicitudes se realicen correctamente) configurando este indicador. Lo dejaría solo si no tiene una buena razón para cambiarlo, no dice nada que pueda romperse (Android Studio, sus aplicaciones, etc.)
  • -Djna.nosys =real – Java Native Access es una biblioteca que facilita a los programas Java el uso de bibliotecas nativas sin la necesidad de JNI u otro código nativo. Cuando se carga JNA, intenta cargar la biblioteca compartida específica de la plataforma y primero la busca en las rutas especificadas jna.boot.library.path, seguido de las rutas de la biblioteca del sistema. Establecer esta bandera en verdadero evita que JNA busque esta biblioteca compartida en las rutas de la biblioteca del sistema. Definitivamente no cambiaría eso si realmente no sabe lo que está haciendo, ya que podría romper sus aplicaciones JVM si inesperadamente usan una versión diferente de la biblioteca compartida JNA. Créame: ¡luchar contra las adicciones de una biblioteca compartida no es un momento divertido!
  • -Djna.boot.library.path = – como se mencionó en el ítem anterior, esto determina el primer lugar que JNA debe buscar en su biblioteca compartida. Debido a esta configuración, creo que intentará encontrar la biblioteca compartida JNA nativa en la ruta de clase de su aplicación.
  • -da – Esto deshabilita las declaraciones de Java en tiempo de ejecución. La mayoría de las veces, probablemente usaría declaraciones en ensamblajes de depuración (o durante las pruebas), pero las desactivaría durante la producción y verificaría los datos de otras formas. Las reclamaciones están deshabilitadas de forma predeterminada, pero esta marca proporciona seguridad adicional. No recomendaría cambiarlo a -ea (para habilitar el reclamo) porque puede causar problemas inesperados en tiempo de ejecución y reducir el rendimiento de la aplicación.
  • -Xverify:ninguna – La JVM cuenta con mecanismos de seguridad que verifican que el código de bytes se haya creado y cargado correctamente. Esta opción desactiva esta verificación. Supongo que está aquí para ayudar a mejorar el rendimiento de Android Studio, pero es muy peligroso usarlo en una aplicación de producción, hasta el punto de que, a partir de Java 13, Oracle ha obsoleto esta opción.
  • -XX: ErrorFile =$ USER_HOME / java_error_in_studio_% p.log – aquí la JVM guarda un registro de todos los errores graves – %p se reemplazará el ID de proceso.
  • -XX: HeapDumpPath =$ USER_HOME / java_error_in_studio.hprof: determina dónde se escribirá el volcado de pila si OutOfMemoryError ocurre un -XX:+HeapDumpOnOutOfMemoryError la bandera está puesta.
  • -XX: MaxPermSize =2 g: controla el espacio máximo de la «generación permanente». Esta es un área de memoria que la JVM reserva para almacenar objetos que nunca serán recolectados como basura, por ejemplo, clases, constantes de cadena, etc. de su programa. Si ves un java.lang.OutOfMemoryError: PermGen space El error de subir es lo primero que hay que intentar. Esto es independiente del montón donde se almacenan las instancias de los objetos (memoria dinámica).

Puttinorteg en conjunto, la siguiente figura muestra los diferentes tipos de memoria utilizados por la JVM (y cómo los diferentes indicadores corresponden a diferentes áreas):

Me gustaría saber de usted: ¿qué opciones de configuración de JVM utiliza y por qué? ¡Escríbeme una nota en los comentarios! Y síganme en el medio si están interesados ​​en recibir notificaciones de piezas futuras.

Este manjar fue descubierto el 2 de octubre de 2020.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *