GC asesinato se reúne desde el principio de la reflexión

prefacio

En primer lugar responder a la pregunta que se trate. Esto es principalmente debido a la presencia de un gran número de reflexiones generadas cargador de clases temporal y ASM clases generadas temporalmente serán retenidos en metaespacio, una vez metaespacio tiempo casi lleno, desencadenará FullGC, la recuperación ha alcanzado la clase ya no se usa el propósito del objeto. Por favor refiérase a las siguientes preguntas específicas de contenido, para lograr una mejor comprensión del principio de reflexión.

texto

contorno

Hay un sistema de gran capacidad de memoria (70G o más) antes de que la compañía ha estado utilizando CMS GC, sino porque el sistema es muy sensible al tiempo, porque gclocker en ocasiones conducen a destacar particularmente largo (aunque la adición de -XX: parámetros + CMSScavReengeBeforeRemark, pero gclocker que podrían causar observación el retraso YGC), no puede soportar una larga pausa tal tenía que pasar a la G1, después de una serie de melodía como relativamente estable, este parámetro será empujado a todas las máquinas en la

Pero la semana pasada, la máquina de repente apareció completa GC, G1 diseñada originalmente se esperaba completo GC no se produce, por lo general no es normal GC completo, registro de GC es el siguiente:

gc.jpg

Desde el registro anterior no es difícil de encontrar debido a la ondulación permanente del gatillo completa GC, GC y después de la completa Perm a bajar, pero es necesario mencionar que JDK7 G1 normal de GC no les gusta de desinstalación, y sólo cuando está lleno GC será desinstalado, pero JDK8 se proporciona bajo los parámetros pertinentes que se puede hacer en la clase descargar algunas GC fase G1

Así que para la parte comercial de coredump hacer en primer lugar, guardar la escena y luego reiniciar el sistema y, a continuación, hizo un volcado de núcleo para la descarga del montón, pero no Heapdump 40G tan grande, se puede echar un vistazo a la forma en la ondulación permanente por jmap -permstat core.xxx Hay algo

Este artículo está relativamente largo, más relacionado con el conocimiento, si no se puede dejar de leer en, puede saltar a la última mirada a mi descripción del problema y luego girar a la lectura de este artículo le puede dar una visión más clara comprensión

¿Qué es exactamente rellena en Perm

Dado que es una permanente completa, entonces tenemos que ver Perm exactamente dónde poner lo que sabemos de Perm en la memoria principal es la clase de los datos en bruto, como el que carga una clase, y que la información de este tipo va a asignar memoria en Perm, donde a la tienda algunos de su estructura de datos, por lo que en la mayoría de los casos, la cantidad de Perm y el número de clases cargadas es una gran relación, por supuesto, en Perm ahorrará algunos otros datos en la versión inferior del tiempo, tal como String (String.intern () caso).

Además la experiencia nos dice que si se trata realmente de desbordamiento de Perm, esa posibilidad tendrá un lugar para construir un cargador carga dinámica de clases Una clase es grande, jmap con el comando anterior, podemos contar el número alcanzado realmente bajo sun.reflect.DelegatingClassLoader la 415 737

Puede ser básicamente bloqueado reflexivo cargador de clases de Perm causa desbordamiento, entonces ¿por qué hay tanto de lo que refleja el cargador de clases, lo que refleja lo que es el cargador de clases, luego decir brevemente que bajo el principio de la reflexión

principios reflejada

Como reflejo de todo el mundo es fácil de usar, ya que el rendimiento es bastante bueno, así que con bastante amplia, por lo que suelen utilizar la reflexión

método Método = XXX.class.getDeclaredMethod (xx, xx); method.invoke (objetivo, params)

Pero aquí no voy a utilizar una gran cantidad de código para describir su principio, pero decir algunas cosas claves, y luego juntos cuerdas

Obtener Método

Método de obtención de la primera llamada, adquirida por la lógica Método de las Clases de esta clase, y varios métodos y propiedades clave como sigue:

class.jpg

Hay en la clase en una propiedad clave llamada reflectionData, en el que el depósito principal se obtuvo de cada JVM, a algunos atributos de clase, como los métodos, campos, etc., es probablemente un largo camino

3.jpg

Esta propiedad es principalmente SoftReference, que es en algunos casos más exigentes de memoria es probable que ser reciclado, pero en circunstancias normales puede -XX: para controlar el momento de la recuperación de SoftRefLRUPolicyMSPerMB este parámetro, cuando se acabe el tiempo, siempre y cuando se producen GC será recuperar, y luego, después de que los medios de recuperación que existe una demanda de la hora de volver a crear uno de estos objetos, pero también es necesario tomar un pedazo de datos de la máquina virtual Java, y que la estructura de datos asociada Método, campo y otros campos se regeneran se objetos. objetos que puedan tener ningún problema si se vuelven a generado? Replicado de entender

getDeclaredMethod método es muy simple, consiste en copiar un objeto Método de la lista devuelta por el método privateGetDeclaredMethods a cambio. Y este proceso de copia se logra mediante searchMethods

Si reflectionData declaredMethods esta propiedad no está vacío, entonces regresar a sus privateGetDeclaredMethods directamente en él, de lo contrario ir a pescar uno de la JVM, y asignado al campo reflectionData, por lo que la próxima vez que puede llamar privateGetDeclaredMethods utilizan los datos almacenados en caché , no siempre ir a buscar los datos transferidos a la JVM, porque es reflectionData Softreference, por lo que existe el riesgo de obtener cualquier valor, teniendo al menos una vez antes de ir a pescar en la JVM

searchMethods de la lista de métodos de privateGetDeclaredMethods encontrar una manera de volver un partido del mismo nombre, y luego copiar un método objeto de la copia de la aplicación específica, de hecho Method.copy método:

4.jpg

Por lo tanto, Método de objetos cada vez que regresamos llamando a métodos getDeclaredMethod son, de hecho, un objeto nuevo, no es apropiado para ajustar Oh, si se llama a menudo la mejor caché. Pero este nuevo enfoque objeto tiene un atributo raíz apunta a un método reflectionData en la memoria caché, la memoria caché mientras su methodAccessor también se utiliza en ese método de methodAccessor.

las llamadas de método

Una vez que tenga Método, puede llamar a su método de invocación, a continuación, echar un vistazo a algunas informaciones clave Método

5.jpg

De hecho, la propiedad raíz se ha dicho más arriba, el punto principal para almacenar en caché el método objeto, que es, la corriente método objeto es en realidad construido de acuerdo con la raíz de este procedimiento, y por lo tanto la presencia de un Método Método raíz de múltiple deriva.

methodAccessor esto es clave, de hecho Method.invoke método es llamar al método de invocación methodAccessor, methodAccessor esta propiedad si la raíz en sí ha sido, sería vienen directamente de asignación methodAccessor de la raíz, de lo contrario se creará una

aplicación MethodAccessor

sí MethodAccessor es una interfaz

6.jpg

Hay tres realización principal

  • DelegatingMethodAccessorImpl
  • NativeMethodAccessorImpl
  • GeneratedMethodAccessorXXX

DelegatingMethodAccessorImpl que es la inyección final de methodAccessor al método, que es un método de todas método de invocación será llamado a esta DelegatingMethodAccessorImpl.invoke, el mismo que su nombre, es el agente, que es la verdadera realización de lo siguiente puede ser dos especie

7.jpg
Si NativeMethodAccessorImpl, que sugiere su nombre, esto se logra principalmente nativa logra, y cada uno tiene que reflejarse GeneratedMethodAccessorXXX método invocado clase generada dinámicamente, después de un número XXX está en constante aumento y se reflejan ir todo el camino NativeMethodAccessorImpl, después de la melodía por defecto de 15 veces, genera una clase GeneratedMethodAccessorXXX, vamos a ir después de generar buena invocación de este método para generar clases de NativeMethodAccessorImpl forma que la transición a GeneratedMethodAccessorXXX él, echar un vistazo invocar el método NativeMethodAccessorImpl
8.jpg
He dicho anteriormente, que es de 15 veces en las que ReflectionFactory.inflationThreshold () Este método devuelve, este 15 supuesto, no es su inmutable, que pueden ser especificados por -Dsun.reflect.inflationThreshold = xxx, también podemos -Dsun .reflect.noInflation = true para omitir el 15 NativeMethodAccessorImpl llaman lo anterior, y -Dsun.reflect.inflationThreshold = 0, el mismo efecto y GeneratedMethodAccessorXXX son, una vez después de que se crea para generar a través de nuevo MethodAccessorGenerator (). generateMethod conjunto de DelegatingMethodAccessorImpl desaparecido, por lo que la próxima Method.invoke será transferido a la recién creada MethodAccessor Lane.

La generada GeneratedMethodAccessorXXX ve exactamente igual que él, este es probablemente el

9.jpg
De hecho, el método específico de llamar directamente al objeto de destino, y no hay diferencia entre las llamadas a métodos normales

cargador de clases GeneratedMethodAccessorXXX

¿Qué carga GeneratedMethodAccessorXXX cargador de clases es que, después de generar un código de bytes buena llama al método siguiente para hacer la definición de clase

10.jpg

Así GeneratedMethodAccessorXXX cargador de clases es en realidad un cargador de clases DelegatingClassLoader

La razón para participar en un nuevo cargador de clases, por razones de rendimiento, y en algunos casos puede desinstalar estas clases generadas, debido a la descarga de la clase es sólo en el caso del cargador de clases pueden ser reciclados serán reciclados, si con el cargador de clases original que pueden causar estos clase recién creada no ha podido ser descargada desde el punto de vista del diseño en sí no queremos que tengan la memoria, cuando sea necesario allí en la línea existe en la memoria cuando esté apretada se puede liberar la memoria

cables de basura concurrentes a la creación de clases

Vea aquí no sé si has encontrado un problema, de hecho, no están por encima de NativeMethodAccessorImpl.invoke bloqueado ¿Qué significa? Si la hora de concurrente, también puede significar que hay muchos hilos para crear lógico clase entrar GeneratedMethodAccessorXXX, de hecho, aunque sólo habrá un uso final, pero estos costes no están ya en existencia, si hay 1.000 hilo han entrado en la lógica creada GeneratedMethodAccessorXXX de, que significa la creación de más de 999 clases no deseados habría sido ocupada la memoria, la GC se puede recuperar hasta que la recuperación se llevará a cabo en Perm

Eso es exactamente lo que los métodos están constantemente reflejarla

Una vez que haya reflejado en la cara de los principios del entendimiento, sabemos que después de un cierto número de veces que debe realizarse la reflexión, de hecho, va a construir una clase dinámica, en esta clase correspondiente a las llamadas a métodos del objeto de destino directamente, como hemos aprendido en el volcado del montón hay una gran cantidad de cargas DelegatingClassLoader cargador de clases de la clase GeneratedMethodAccessorXXX, y que al final estas clases se llama ¿qué métodos, por lo que tenemos que hacer una cosa, y que es la memoria de estas clases vierten hacia abajo, y luego hacer el código de bytes analizar una estadística

Volcado de código de bytes de clases en tiempo de ejecución

Podemos utilizar la interfaz SA de volcado de núcleo en curso o en vivo en el correspondiente abajo volcado clase, para volcar hacia abajo nuestra clase en particular, de primera clase escribimos un filtro

11.jpg

El uso de SA frasco ($ JAVA_HOME / lib / sa-jdi.jar) compilado después de clase, entonces llamamos al comando siguiente para volcar la clase compilada en el directorio

12.jpg

De manera que todos podemos GeneratedMethodAccessor para volcar hacia abajo, y esta vez sólo tendremos que mirar el código de bytes de una clase por javap -verbose GeneratedMethodAccessor9

12.jpg

Ver más arriba BCI clave de la línea 36, ​​donde el método es el método que llamamos la reflexión, como por ejemplo el llamado método de reflexión anterior es org / Codehaus / Xfire / util / ParamReader.readCode

clases y métodos específicos objetivo reflectantes

Después de estos volcado código de bytes, que hacemos un byte de código de todos estos clase de estadísticas, a encontrar toda método llamado la reflexión, y luego encontrar alguna clase de modelo (paquete es el mismo) en realidad produce más de 20 diez mil clase, lo que significa que hay una gran cantidad de estas clases del modelo no reflexión

13.jpg
Con esta clave es cuidar el código exactamente donde habrá un reflejo lógico llamar a estos métodos de modelo, pero por desgracia no se encontró, pero este modelo es altamente probable que el objetivo en algunos casos, es el momento de deserialización RPC, la fiesta final está pidiendo Xfire uso de los servicios de negocio, y con la experiencia que han acumulado muchos años de marco de desarrollo, es determinar los objetos deserializar Xfire por medio de la reflexión, el código específico de la siguiente manera (org.codehaus.xfire.aegis.type.basic .BeanType.writeProperty):
14.jpg
El JavaBean de PropertyDeor en el get / métodos set, de hecho, el propio envase es SoftReference
14.jpg

Vemos aquí tal vez todos lo entendemos, ha dicho antes que es posible recuperar GC SoftReference a cabo, el tiempo viene que se recuperará en la próxima GC, si se recuperó, tendría que volver a adquirir, a continuación, el equivalente de nuevo objeto método de invocación llamadas de método, las llamadas que más de un número, se tendrá que construir una nueva clase dinámica, y esta clase siempre será guardado en un GC hasta que pueda ser recuperado Perm

G1 recuperó Perm

Tenga en cuenta que bajo el sistema operativo utiliza G1 JDK7 y JDK7 el G1 a la ondulación permanente de hecho en circunstancias normales no se recicla, solamente se recuperará cuando se completa GC en Perm, lo que explica después de un número de G1 GC, Softreference se recuperarán esos objetos, pero no se recuperará la clase recién creada y, de hecho, por lo que el GC G1 más frecuentes, que significa que los objetos más probable SoftReference a ser recuperados (aunque en circunstancias normales es a tiempo, pero si no es con frecuencia GC , incluso si el tiempo se ha acabado, se quedará en la memoria de), más probabilidades de ser recuperado y que cuanto más fácil es producir una nueva clase hasta que se produzca la completa GC

soluciones

  • La actualización a jdk8, se puede hacer la clase en proceso de descarga G1 GC
  • Para una secuencia de protocolo, el método no tiene la reflexión, tal como arpillera
  • SoftRefLRUPolicyMSPerMB ajustar este parámetro aumenta, pero esto no es una cura permanente

resumen

Lo anterior se relaciona con mucho, si no más que leer varias veces, puede ser difícil de hilar, voy a estar aquí esta situación se produjo más o menos describir el problema:

Este sistema utiliza JDK7 bajo G1, y esta versión de la G1 sólo lo hará la clase de Perm en el GC completa descargada en el momento del sistema debido a que un gran número de solicitudes que resulten en G1 GC sucede muy a menudo, pero el sistema también está configurado -XX : SoftRefLRUPolicyMSPerMB = 0, lo que significa SoftReference ciclo de vida no se mueve GC cruz, puede rápidamente recuperar perdido, hay una gran cantidad de llamadas RPC este sistema, caminando acuerdo Xfire para devolver los resultados hacen tiempo deserialización es ir lógica Method.invoke, y método asociado, por tanto, referencia SoftReference, que puede ser fácilmente reciclado, se recuperó una vez, sería crear un nuevo método objeto, a continuación, llamar a su método de invocación, después de una llamada a un número determinado de veces (15 veces) , para construir una nueva clase de código de bytes, junto con la realización de la GC, clase de código de bytes con un método de construcción de forma continua hasta que el gatillo Perm completa un GC completo era capaz de liberación

lectura recomendada

Una vez que el producto investigación 100% práctica optimización de la CPU

Hablar de una aplicación Java a partir de un caso real de optimización GC

Supongo que te gusta

Origin juejin.im/post/5e8ed12bf265da47d00a58f8
Recomendado
Clasificación