A través del código fuente de mybatis, analice un OutOfMemoryError causado por un uso inadecuado de mybatis.

    Se dice que mybatis se usa incorrectamente, pero en realidad no es exacto. Debería decirse que no entiendo algunos de los mecanismos de funcionamiento de mybatis. A continuación, que todos analicen el código fuente de mybatis y comprendan las razones de esta OOM en línea.

    Primero, ¿entiende qué es OOM?

    OOM Out Of Memory es la abreviatura de traducción al chino: desbordamiento de memoria dice en Wikipedia: desbordamiento de memoria (sin memoria) el entendimiento popular es que la memoria no es suficiente, generalmente cuando se ejecuta software o juegos a gran escala, software o juegos que requieren mucha más memoria Exceder la capacidad de la memoria instalada en su host se denomina desbordamiento de memoria.

    En un entorno de producción, la memoria no es infinita y los recursos de memoria también son valiosos. En un entorno de producción, cada servidor puede implementar múltiples aplicaciones. Si se usa tecnología virtual o tecnología de contenedores, se pueden implementar en un servidor. Miles de aplicaciones, para que el uso de memoria entre aplicaciones no se afecte entre sí, solemos limitar el máximo de memoria que puede utilizar cada aplicación jvm. Cuando la memoria requerida por nuestra aplicación supera este máximo, la memoria se desbordará provocando que todo el usuario cuelgue. No se aplicará a la memoria ilimitada y se aplicará a otras aplicaciones.

    Por lo general, la memoria asignada en línea se proporciona después de una evaluación razonable. Cumple con los requisitos de uso en línea y se produce un desbordamiento de la memoria. La mayoría de ellos se deben a una escritura de código insuficiente, que ocupará demasiada memoria en poco tiempo, o una pérdida de memoria (usando Una vez que la memoria no se libera, se acumula gradualmente).

    También hay muchas herramientas para analizar OOM. Generalmente uso el plug-in Eclipse Memory Analyzer para eclipse. Las   capturas de pantalla que  proporcionaré a continuación también se basan en Eclipse Memory Analyzer .

Hace unos días, recibí una alarma de la plataforma en línea, diciendo que ocurrió un OOM en un servidor, obtuve el archivo de volcado y comencé el análisis:

Puede ver que hay 3 supuestas fugas graves, que utilizan casi 4,7 G de memoria.

Luego ingrese al análisis de Detalles:

Hay una ArrayList en DefaultResultHandler en Thread-1606 que contiene muchos objetos, estos son nuestros objetos comerciales XXXInfo.

¿Por qué hay tantos XXInfo almacenados aquí, y luego mira hacia abajo: el enlace en la primera imagen, Ver seguimiento de pila, haga clic en

A través de este Thread Stack, podemos localizar rápidamente el código. Sin nuestro código, hay una consulta selectOne que devuelve el objeto XXXInfo. Hay demasiado uso en el código selectOne, tomó tanto tiempo y no hay problema. Luego vimos el código fuente de mybatis,

看org.apache.ibatis.session.defaults.DefaultSqlSession.selectOne 方法 

Resulta que selectOne es el método selectList llamado. Los datos se envían a ArryList y luego se juzgan por list.size. Fui al registro y verifiqué TooManyResultsException. Resultó que había una excepción:

¡Entonces Hola! 3199254 objetos, finalmente lo entiendo: resulta que nuestro sql originalmente quería consultar un fragmento de datos, pero no esperaba encontrar 300w y el selectOne de mybatis resultó poner todos los 300w en la matriz, y luego devolvió una excepción. Es lógico, siempre Después de la ejecución, los datos ya no se utilizan, la memoria se liberará y no debería ocupar demasiada memoria, ¡pero mybatis tiene un caché! Veamos el código fuente nuevamente:

Seguimos y encontramos que los datos se colocaron en el localCache de mybatis,

Caché permanente tipo PerpetualCache, almacenado en el ejecutor (BaseExecutor), el caché de primer nivel, también llamado caché local

¡Dios! Revisé un registro, esta excepción se lanzó más de diez veces, es decir, 300w * 10 objetos, si no hay desbordamiento en ese momento, se estima que habrá más errores de consulta hasta que la memoria se bloquee. ¡Aquí puedes ir a modificar el código!

 

En resumen: el principal problema aquí es por qué selectOne devolverá varias preguntas. De hecho, esto no es un bote de mybatis. Es más un problema con nuestra lógica comercial o datos. Al reparar la lógica o los datos del código, los problemas anteriores se resolverán de manera efectiva. Pero después de comprender este mecanismo de mybatis, ¡nos ayudará a escribir un código más robusto!

Supongo que te gusta

Origin blog.csdn.net/kevin_mails/article/details/84982006
Recomendado
Clasificación