JavaRush /Blog Java /Random-ES /Una guía para administrar la memoria Java (y guardar su c...
pandaFromMinsk
Nivel 39
Минск

Una guía para administrar la memoria Java (y guardar su código)

Publicado en el grupo Random-ES
Nota del traductor: el deseo de traducir la nota apareció temprano en una mañana de junio después de leerla medio dormido en un vagón del metro. Público objetivo: personas que están dando sus primeros pasos en el mundo de Java y, debido a la naturaleza de su formación técnica básica o su deseo, están muy ansiosas por sumergirse en Java y aprender todos los procesos "electrodinámicos". Estoy seguro de que para quienes lean esto, este será el punto de partida de un viaje al mundo de la configuración de JVM y GC. ¡Viento justo! Artículo original aquí Como desarrollador, pasa incontables horas limpiando errores de una aplicación Java y obteniendo el rendimiento necesario. Durante las pruebas, observa que la aplicación se ejecuta gradualmente más lentamente y, al final, falla por completo o simplemente muestra un rendimiento deficiente. Finalmente acepte que se producen pérdidas de memoria. El recolector de basura Java hace todo lo posible para solucionar estas fugas. Pero hay muchas cosas que se pueden hacer cuando nos enfrentamos a situaciones como estas. Necesita formas de identificar llamadas de pérdida de memoria, identificar causas y comprender el papel del recolector de basura de Java a la hora de afectar el rendimiento general de la aplicación.

Principales síntomas de las pérdidas de memoria de Java

Hay varios síntomas que indican que una aplicación tiene problemas de pérdida de memoria. Una ligera disminución en el rendimiento, en lugar de un fallo repentino de la aplicación, sólo indica una pérdida de memoria. El problema puede ocurrir cada vez durante el funcionamiento o solo cuando la aplicación comienza a funcionar con una gran cantidad de datos o, por el contrario, comienza a escalar la aplicación. La aplicación probablemente mostrará un error de falta de memoria una vez que la fuga haya consumido todos los recursos de memoria disponibles. Si reinicia la aplicación y espera lo mejor, encontrará fallas repetidas hasta que se solucione la fuga. En general, las pérdidas de memoria ocurren cuando se acumulan referencias a objetos en lugar de liberar memoria. Ocupan toda la memoria disponible y hacen imposible que la aplicación acceda a los recursos que necesita.

Errores de configuración que aparecen como pérdidas de memoria.

Antes de analizar situaciones que causan problemas de memoria en Java y realizar un análisis, debe asegurarse de que la investigación no esté relacionada con un problema completamente diferente. Algunos errores de falta de memoria ocurren debido a varios errores, como errores de configuración. Es posible que la aplicación tenga poca memoria dinámica o que esté en conflicto con otras aplicaciones del sistema. Si empieza a hablar de problemas de poca memoria pero no puede descubrir qué está causando la fuga, eche un vistazo diferente a la aplicación. Descubrirá que necesita realizar cambios en el hilo de finalización o aumentar la cantidad de espacio de generación permanente, que es un área de la memoria JVM para almacenar descripciones de clases Java y algunos datos adicionales.

Beneficios de las herramientas de monitoreo de memoria

Las herramientas de monitoreo de memoria brindan una mayor visibilidad del uso de los recursos disponibles por parte de una aplicación Java. Al utilizar este software, das un paso para limitar la búsqueda de la raíz del problema de las pérdidas de memoria y otros incidentes de rendimiento. Las herramientas se dividen en varias categorías y es posible que necesite utilizar una variedad de aplicaciones para descubrir cómo señalar correctamente el problema y qué salió mal, incluso si se trata de pérdidas de memoria. Los archivos de volcado de montón proporcionan la información necesaria para analizar la memoria Java. En este caso, es necesario utilizar dos herramientas: una para generar un archivo de volcado y otra para un análisis detallado. Esta solución proporciona información detallada sobre lo que está sucediendo con la aplicación. Una vez que la herramienta señala las ubicaciones de posibles problemas y trabaja para reducir el área para descubrir la ubicación exacta del incidente. Y este período de tiempo es el de la parte más larga y deprimente de prueba y error. El analizador de memoria indica varios problemas en su código, pero no está absolutamente seguro de qué problemas está encontrando su aplicación. Si aún encuentra el mismo error, comience de nuevo y trabaje en otro posible error. Realice un cambio a la vez e intente duplicar el error. Deberá dejar que la aplicación se ejecute durante algún tiempo para duplicar las condiciones de error. Si hay una pérdida de memoria durante la primera prueba, asegúrese de cargar la aplicación. Una aplicación puede funcionar bien con una pequeña cantidad de datos, pero puede volver a generar los mismos errores cuando trabaja con una gran cantidad de datos. Si persiste el mismo error, deberá empezar de nuevo y buscar otra posible causa. Las herramientas de monitoreo de memoria demuestran su utilidad una vez que la aplicación está en pleno funcionamiento. Puede monitorear de forma remota el rendimiento de JVM y detectar proactivamente situaciones de falla antes de que un desarrollador se sumerja en el problema y recopile datos históricos de rendimiento para ayudar a mejorar sus técnicas de programación en el futuro y ver cómo se desempeña Java bajo una carga pesada. Muchas soluciones incluyen modos de alerta de "peligro" u otros modos similares para que el desarrollador pueda saber inmediatamente qué va mal. Todo desarrollador no quiere que una aplicación crítica, mientras está en producción, falle y provoque la pérdida de decenas o cientos de miles de dólares durante el tiempo de inactividad de la aplicación, por lo que las herramientas de monitoreo de memoria reducen el tiempo de respuesta del desarrollador. Las aplicaciones de monitoreo de memoria le permiten iniciar el proceso de diagnóstico instantáneamente, en lugar de pedirle que vaya al cliente, donde nadie le dirá exactamente qué error ocurrió o qué código de error generó la aplicación. Si a menudo se encuentra inmerso en problemas de memoria y rendimiento de su aplicación Java, profundice en el proceso de prueba. Identifique cada área débil en el proceso de desarrollo y cambie sus estrategias de prueba. Consulte con colegas y compare sus enfoques de prueba con las mejores prácticas existentes. A veces es necesario revisar un pequeño fragmento de código y luego garantizar un impacto duradero en toda la aplicación.

Papel del recolector de basura en la memoria de Java y las pérdidas de memoria

Garbage Collector en Java juega un papel clave en el rendimiento de las aplicaciones y el uso de la memoria. Busca objetos no utilizados (muertos) y los elimina. Estos objetos ya no ocupan memoria, por lo que su aplicación continúa garantizando la disponibilidad de recursos. A veces, la aplicación no le da al GC suficiente tiempo o recursos para eliminar los objetos muertos y se acumulan. Puede encontrarse con una situación en la que haya acceso activo a objetos que cree que están muertos. El recolector de basura no puede hacer nada al respecto porque... su mecanismo automatizado de gestión de memoria pasa por alto los objetos activos. Normalmente, el recolector de basura funciona de forma autónoma, pero es necesario ajustar su comportamiento para responder a problemas graves de memoria. Sin embargo, el propio GC puede causar problemas de rendimiento.

áreas de GC

El recolector de basura separa los objetos en diferentes áreas para optimizar el ensamblaje. Young Generation presenta objetos que desaparecen rápidamente. El recolector de basura suele trabajar en esta zona desde el momento en que tiene que limpiar. Los objetos que permanecen vivos después de alcanzar un cierto período se transfieren a la Vieja Generación. En el área Old Generation, los objetos permanecen durante mucho tiempo y el coleccionista no los retira con tanta frecuencia. Sin embargo, cuando el recolector se ejecuta en el alcance, la aplicación pasa por una operación grande en la que el recolector examina los objetos activos para limpiar la basura. Como resultado, los objetos de aplicación se encuentran en el área de generación permanente final. Normalmente, estos objetos incluyen los metadatos de JVM necesarios. La aplicación no genera mucha basura en la generación permanente, pero necesita un recolector para eliminar clases cuando ya no son necesarias.

Relación entre Garbage Collector y tiempo de respuesta

El recolector de basura, independientemente de la prioridad de ejecución de los subprocesos de la aplicación, los detiene sin esperar a que finalicen. Este fenómeno se llama evento "Stop the World". La región de Generación Joven del recolector de basura tiene un impacto menor en el rendimiento, pero los problemas son notables si el GC realiza una limpieza intensiva. Terminas en una situación en la que el GC menor de la Generación Joven se ejecuta constantemente o la Generación Vieja entra en un estado incontrolado. En tal situación, es necesario equilibrar la frecuencia de la Generación Joven con el rendimiento que requiere aumentar el tamaño de esta área del colector. Las regiones de generación permanente y antigua del recolector de basura tienen un impacto significativo en el rendimiento de la aplicación y el uso de la memoria. Esta importante operación de limpieza de basura pasa por el montón para expulsar los objetos muertos. El proceso lleva más tiempo que una compilación menor y el impacto en el rendimiento puede tardar más. Cuando la intensidad de fregado es alta y el tamaño del área de la Vieja Generación es grande, el rendimiento de toda la aplicación se estanca debido a eventos de "Detener el mundo". La optimización de la recolección de basura requiere monitorear la frecuencia con la que se ejecuta un programa, el impacto en el rendimiento general y cómo ajustar la configuración de la aplicación para reducir la frecuencia de monitoreo. Es posible que necesite identificar el mismo objeto colocado más de una vez sin que la aplicación tenga que separarse de la ubicación, o puede que necesite encontrar los puntos de compresión que están frenando a todo el sistema. Para lograr el equilibrio adecuado es necesario prestar mucha atención a todo, desde la carga de la CPU hasta los ciclos del recolector de basura, especialmente si las generaciones jóvenes y antiguas están desequilibradas. Abordar las pérdidas de memoria y optimizar la recolección de basura ayuda a mejorar el rendimiento de una aplicación Java. Literalmente estás haciendo malabares con muchas partes móviles. Pero con el enfoque de resolución de problemas adecuado y las herramientas de análisis diseñadas para proporcionar una visibilidad rigurosa, llegará a la luz al final del túnel. De lo contrario, sufrirá problemas relacionados con el rendimiento. La cuidadosa ubicación y supervisión de la memoria desempeñan un papel fundamental en una aplicación Java. Debe tomar el control total de la interacción entre la recolección de basura, la eliminación de objetos y el rendimiento para optimizar su aplicación y evitar errores de falta de memoria. Las herramientas de monitoreo lo ayudan a estar al tanto de posibles problemas y resaltar las tendencias de utilización de la memoria para que pueda adoptar un enfoque proactivo en la resolución de problemas. Las pérdidas de memoria a menudo muestran la ineficacia de la solución de problemas normal, especialmente si encuentra valores de parámetros de configuración incorrectos, pero abordar los problemas de memoria puede ayudarlo a evitar rápidamente incidentes que se interpongan en su camino. La perfección del ajuste de la memoria de Java y GC hace que su proceso de desarrollo sea mucho más fácil.
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION