1. Información general
En este artículo, analizaremos las API proporcionadas por Java que pueden ayudarnos a comprender los diversos aspectos relacionados con el espacio de almacenamiento dinámico de Java.
Esto puede ser útil para comprender el estado actual de la memoria de la JVM y subcontratarlo a servicios de monitoreo como StatsD y Datadog, que luego se pueden configurar para tomar medidas preventivas y evitar fallas en las aplicaciones.
2. Acceso a los parámetros de memoria
Cada aplicación Java tiene una única instancia de java.lang.Runtime que puede ayudarnos a comprender el estado actual de la memoria de la aplicación. Se puede llamar al método estático Runtime # getRuntime para obtener la instancia de singleton Runtime .
2.1. Memoria total
El método Runtime # getTotalMemory devuelve el espacio de almacenamiento dinámico total reservado actualmente por la JVM en bytes. Incluye la memoria reservada para objetos actuales y futuros. Por lo tanto, no se garantiza que sea constante durante la ejecución del programa, ya que el espacio del montón de Java se puede expandir o reducir a medida que se asignan más objetos.
Además, este valor no es necesariamente el que está en uso o la memoria máxima disponible.
2.2. Memoria libre
El método Runtime # freeMemory devuelve el espacio de pila libre disponible para nuevas asignaciones de objetos en bytes. Puede aumentar como resultado de una operación de recolección de basura en la que después hay más memoria libre disponible.
2.3. Memoria maxima
El método Runtime # maxMemory devuelve la memoria máxima que la JVM intentará utilizar. Una vez que el uso de la memoria de la JVM alcanza este valor, no asignará más memoria y, en cambio, recolectará basura con más frecuencia.
Si los objetos de la JVM aún necesitan más memoria incluso después de ejecutar el recolector de basura, la JVM puede generar una excepción de tiempo de ejecución java.lang.OutOfMemoryErro .
3. Ejemplo
En el siguiente ejemplo, inicializamos una ArrayList y le agregamos elementos mientras realizamos un seguimiento del espacio de almacenamiento dinámico de JVM utilizando los tres métodos anteriores:
ArrayList arrayList = new ArrayList(); System.out.println("i \t Free Memory \t Total Memory \t Max Memory"); for (int i = 0; i < 1000000; i++) { arrayList.add(i); System.out.println(i + " \t " + Runtime.getRuntime().freeMemory() + " \t \t " + Runtime.getRuntime().totalMemory() + " \t \t " + Runtime.getRuntime().maxMemory()); } // ...
Output: i Free Memory Total Memory Max Memory 0 254741016 257425408 3817865216 1 254741016 257425408 3817865216 ... 1498 254741016 257425408 3817865216 1499 253398840 257425408 3817865216 1500 253398840 257425408 3817865216 ... 900079 179608120 260046848 3817865216 900080 302140152 324534272 3817865216 900081 302140152 324534272 3817865216 ...
- Fila 1498: el valor Runtime # freeMemory disminuye cuando se asigna suficiente espacio a los objetos en el montón de Java.
- Fila 900080: En este punto, la JVM tiene más espacio disponible ya que GC se ha ejecutado, por lo tanto, los valores de Runtime # freeMemory y Runtime # totalMemory aumentan.
Se espera que los valores que se muestran arriba sean diferentes en cada ejecución de una aplicación Java.
4. Personalización de parámetros de memoria
Podemos anular los valores predeterminados para los parámetros de memoria de la JVM configurando valores personalizados para ciertos indicadores cuando ejecutamos nuestro programa Java para lograr el rendimiento de memoria requerido:
- -Xms: el valor asignado a la bandera -Xms establece el valor inicial y mínimo del montón de Java. Se puede utilizar en los casos en que nuestra aplicación requiera más memoria que el mínimo predeterminado al iniciar la JVM.
- -Xmx: Del mismo modo, podemos establecer el valor máximo para el espacio de pila asignándolo al indicador -Xmx . Se puede usar cuando queremos limitar la cantidad de memoria que usará nuestra aplicación, a propósito.
Tenga en cuenta también que el valor -Xms debe ser igual o menor que el valor -Xmx .
4.1. Uso
java -Xms32M -Xmx64M Main Free Memory : 31792664 bytes Total Memory : 32505856 bytes Max Memory : 59768832 bytes java -Xms64M -Xmx64M Main Free Memory : 63480640 bytes Total Memory : 64487424 bytes Max Memory : 64487424 bytes java -Xms64M -Xmx32M Main Error occurred during initialization of VM Initial heap size set to a larger value than the maximum heap size
5. Conclusión
En este artículo, hemos visto cómo recuperar métricas de memoria JVM a través de la clase Runtime . Estos métodos pueden resultar útiles cuando se investigan las pérdidas de memoria de la JVM y otros problemas relacionados con el rendimiento de la memoria de la JVM.
También mostramos cómo asignar valores personalizados para ciertos indicadores que conducen a diferentes comportamientos de la memoria JVM para diferentes escenarios.