vertical - swing fillers java
¿Hay alguna manera de reducir el montón de Java cuando no está en uso? (6)
La JVM no funciona de esa manera. No puedes devolverlo al sistema operativo.
Como señalaron varias personas desde que se escribió hace cuatro años, puede devolver la memoria al sistema operativo si le da la configuración correcta del GC a la JVM.
Estoy trabajando en una aplicación Java en este momento y estoy trabajando para optimizar su uso de memoria. Estoy siguiendo las pautas para la recogida adecuada de basura, hasta donde yo sé. Sin embargo, parece que mi montón parece estar en su tamaño máximo, a pesar de que no es necesario.
Mi programa ejecuta una tarea de uso intensivo de recursos una vez por hora, cuando una persona no utiliza la computadora. Esta tarea utiliza una buena porción de memoria, pero luego la libera inmediatamente después de que la tarea finaliza. El generador de perfiles de NetBeans revela que el uso de memoria se ve así:
Realmente me gustaría devolver todo ese espacio dinámico al sistema operativo cuando no esté en uso. No hay ninguna razón para que lo acapare mientras que el programa ni siquiera hará nada por al menos otra hora.
es posible? Gracias.
El secreto mejor guardado de Java: -Xincgc Tiene un impacto en el rendimiento pero no siempre es tan grande. A veces sí lo hace, depende de lo que estés haciendo. ¡El recolector de basura incremental devuelve la memoria al sistema bastante bien!
Si su aplicación está en reposo durante períodos de inactividad, es posible que el sistema operativo cambie esas páginas por usted, mitigando su presión sobre la memoria física.
http://www.linuxvox.com/2009/10/what-is-the-linux-kernel-parameter-vm-swappiness/
Una posibilidad es hacer que su aplicación java de fondo inicie una instancia de jvm externa cada hora para ejecutar su tarea. De esta forma, solo su aplicación jvm original se ejecuta entre tareas.
Versión corta: Sí, puedes.
Versión larga:
Cómo maneja Java / JVM la memoria
Para la mayoría de las aplicaciones, los valores predeterminados de JVM son correctos. Parece que la JVM espera que las aplicaciones se ejecuten solo durante un período de tiempo limitado. Por lo tanto, no parece liberar memoria por sí mismo.
Para ayudar a la JVM a decidir cómo y cuándo realizar la recolección de basura, se deben proporcionar los siguientes parámetros:
-
-Xms
Especifica el tamaño mínimo de-Xms
dinámico -
–Xmx
Especifica el tamaño de–Xmx
dinámico máximo
Para aplicaciones de servidor, agregue: -server
Eso no es suficiente para mí. ¡Quiero más control!
En caso de que los parámetros mencionados anteriormente no sean suficientes, puede influir en el comportamiento de la JVM con respecto a la recolección de basura.
Primero, puede usar System.gc()
para indicarle a la VM cuándo cree que la recolección de basura tendría sentido. Y segundo, puede especificar cuál de los recolectores de basura debe usar la JVM:
Diferentes tipos de recolectores de basura:
Serial GC
Parámetro de línea de comando:
-XX:+UseSerialGC
Detiene su aplicación y realiza GC.
Paralelo GC
Parámetro de línea de comando:
-XX:+UseParallelGC -XX:ParallelGCThreads=value
Ejecuta colecciones menores en paralelo con su aplicación. Reduce el tiempo necesario para colecciones importantes , pero usa otro hilo.
Parallel Compacting GC
Parámetro de línea de comando:
-XX:+UseParallelOldGC
Ejecuta colecciones importantes en paralelo con su aplicación. Utiliza más recursos de CPU, reduce el uso de memoria.
CMS GC
Parámetro de línea de comando:
-XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+CMSParallelRemarkEnabled -XX:CMSInitiatingOccupancyFraction=value -XX:+UseCMSInitiatingOccupancyOnly
Realiza colecciones más pequeñas, y más a menudo que Serial GC , lo que limita las interrupciones / paradas de la aplicación.
G1
Parámetro de línea de comando:
-XX:+UnlockExperimentalVMOptions -XX:+UseG1GC
Experimental (al menos en Java 1.6): intenta asegurarse de que la aplicación nunca se detiene durante más de 1s.
Ejemplo
Uso de memoria de una aplicación web de Play Framework sin optimizaciones: Como puede ver, utiliza bastante espacio de montón, y el espacio utilizado se libera regularmente.
En este caso, las optimizaciones con parámetros solo no fueron efectivas. Hubo algunas tareas programadas que usaron bastante memoria. En este caso, el mejor rendimiento se logró utilizando el CMS GC
combinado con System.gc()
después de las operaciones de memoria intensiva. Como resultado, el uso de la memoria de la aplicación web se redujo de 1,8 GB a alrededor de 400-500 MB.
Aquí puede ver otra captura de pantalla de VisualVM que muestra cómo la JVM libera la memoria y la devuelve al sistema operativo:
Nota: Utilicé el botón "Realizar GC" de VisualVM para realizar el GC en lugar de System.gc()
en mi código, ya que las tareas programadas que consumen la memoria solo se inician en momentos específicos y es algo más difícil de capturar con VisualVM .
Otras lecturas
Quizás -XX:MaxHeapFreeRatio
jugar con -XX:MaxHeapFreeRatio
: este es el porcentaje máximo (por defecto 70) del montón que está libre antes de que el GC lo reduzca. Tal vez establecerlo un poco más bajo (40 o 50?) Y luego usar System.gc()
podría tomar algunas medidas para obtener el comportamiento deseado.
Sin embargo, no hay forma de forzar esto, puedes intentar y alentar a la JVM a que lo haga, pero no puedes simplemente arrancar la memoria cuando y como quieras. Y aunque lo anterior puede reducir el montón, esa memoria no se entregará directamente al sistema operativo (aunque en las implementaciones recientes de la JVM sí lo hace).