Grupo constante de clase

     El grupo de constantes de clase puede entenderse como un almacén de recursos en el archivo de clase. Además del archivo de clase que contiene las versiones de la clase, los campos, los métodos y la información de descripción de la interfaz, hay una información de grupo constante (tabla de grupo constante), para almacenar una variedad de literales generados por el compilador (el literal) y referencias simbólicas ( Referencias simbólicas).

La estructura hexadecimal de un archivo de clase es la siguiente: el
Inserte la descripción de la imagen aquí
significado correspondiente es el siguiente, puede consultar el documento oficial de Oracle para obtener más detalles.
Inserte la descripción de la imagen aquí
Por supuesto, generalmente no analizamos este archivo de código de bytes hexadecimal manualmente, generalmente podemos generarlo a través del comando javap Archivo de instrucciones de
código de bytes JVM más legible: javap -v Math.class

Classfile /E:/open/demo/target/classes/com/example/demo/test/opencv/Math.class
  Last modified 2020-9-20; size 619 bytes
  MD5 checksum f70c67abc97af9f0978a807380fcb072
  Compiled from "Math.java"
public class com.example.demo.test.opencv.Math
  minor version: 0
  major version: 52
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
   #1 = Methodref          #5.#26         // java/lang/Object."<init>":()V
   #2 = Class              #27            // com/example/demo/test/opencv/Math
   #3 = Methodref          #2.#26         // com/example/demo/test/opencv/Math."<init>":()V
   #4 = Methodref          #2.#28         // com/example/demo/test/opencv/Math.compute:()I
   #5 = Class              #29            // java/lang/Object
   #6 = Utf8               <init>
   #7 = Utf8               ()V
   #8 = Utf8               Code
   #9 = Utf8               LineNumberTable
  #10 = Utf8               LocalVariableTable
  #11 = Utf8               this
  #12 = Utf8               Lcom/example/demo/test/opencv/Math;
  #13 = Utf8               compute
  #14 = Utf8               ()I
  #15 = Utf8               a
  #16 = Utf8               I
  #17 = Utf8               b
  #18 = Utf8               c
  #19 = Utf8               main
  #20 = Utf8               ([Ljava/lang/String;)V
  #21 = Utf8               args
  #22 = Utf8               [Ljava/lang/String;
  #23 = Utf8               math
  #24 = Utf8               SourceFile
  #25 = Utf8               Math.java
  #26 = NameAndType        #6:#7          // "<init>":()V
  #27 = Utf8               com/example/demo/test/opencv/Math
  #28 = NameAndType        #13:#14        // compute:()I
  #29 = Utf8               java/lang/Object
{
    
    
  public com.example.demo.test.opencv.Math();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1                  // Method java/lang/Object."<init>":()V
         4: return
      LineNumberTable:
        line 3: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       5     0  this   Lcom/example/demo/test/opencv/Math;

  public int compute();
    descriptor: ()I
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=4, args_size=1
         0: iconst_1
         1: istore_1
         2: iconst_2
         3: istore_2
         4: iload_1
         5: iload_2
         6: iadd
         7: bipush        10
         9: imul
        10: istore_3
        11: iload_3
        12: ireturn
      LineNumberTable:
        line 6: 0
        line 7: 2
        line 8: 4
        line 9: 11
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      13     0  this   Lcom/example/demo/test/opencv/Math;
            2      11     1     a   I
            4       9     2     b   I
           11       2     3     c   I

  public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=3, args_size=1
         0: new           #2                  // class com/example/demo/test/opencv/Math
         3: dup
         4: invokespecial #3                  // Method "<init>":()V
         7: astore_1
         8: aload_1
         9: invokevirtual #4                  // Method compute:()I
        12: istore_2
        13: return
      LineNumberTable:
        line 14: 0
        line 15: 8
        line 16: 13
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      14     0  args   [Ljava/lang/String;
            8       6     1  math   Lcom/example/demo/test/opencv/Math;
           13       1     2 compute   I
}
SourceFile: "Math.java"

Hay principalmente dos tipos de constantes almacenadas en el grupo de constantes: referencias literales y simbólicas .

Literales
literales se refiere a una cadena de letras, números o constantes numéricas similares el
valor literal solo puede aparecer a la derecha, llamado valor correcto es el valor a la derecha del signo igual, como por ejemplo: int a = 1 aquí es un valor a la izquierda 1 es el valor correcto. En este ejemplo, 1 es la cantidad literal.

int a = 1; 
int b = 2; 
int c = "abcdefg";

Referencia de símbolo La referencia de
símbolo es un concepto en el principio de compilación, que es relativo a la referencia directa. Incluye principalmente los siguientes tres tipos de constantes:

  • Nombres de clases e interfaces completamente calificados
  • Nombre de campo y descriptor

  •      La a y la b encima del nombre del método y el descriptor son los nombres de campo, que es una referencia simbólica, y Lcom / example / demo / test / opencv / Math en el grupo constante de la clase Math es el nombre completo de la clase, main y compute Es el nombre del método, () es un descriptor en formato UTF8, estos son referencias a símbolos.
          Estos grupos de constantes ahora son información estática. Solo cuando se cargan en la memoria en tiempo de ejecución, estos símbolos tienen la información de dirección de memoria correspondiente. Una vez que estos grupos de constantes se cargan en la memoria, se convierten en grupos de constantes de tiempo de ejecución. Las referencias de símbolos correspondientes están en Cuando el programa se carga o se ejecuta, se convertirá en una referencia directa al código cargado en el área de memoria, que es lo que llamamos enlace dinámico. Por ejemplo, la referencia simbólica de compute () se convertirá en la dirección de memoria del código específico del método compute () en tiempo de ejecución, y la referencia directa se convierte principalmente a través del puntero de tipo en el encabezado del objeto.

Jdk1.6 y antes: hay una generación permanente, y la reserva constante está en el área de método.
Jdk1.7: Hay una generación permanente, pero ha sido gradualmente "de-permanente". La reserva constante está en la pila
Jdk1.8 y posteriores: no hay generación permanente, y la reserva constante está en el yuan espacio

Grupo constante de cadenas

Ideas de diseño de String Constant Pool

  1. La asignación de cadenas, como otras asignaciones de objetos, consume un alto costo de tiempo y espacio.Como el tipo de datos más básico, se crea una gran cantidad de cadenas frecuentes, lo que afecta en gran medida el rendimiento del programa.
  2. Para mejorar el rendimiento y reducir la sobrecarga de memoria, JVM ha realizado algunas optimizaciones al crear instancias de constantes de cadena


Cree un grupo de constantes de cadena para una cadena, similar a un área de búfer. Al crear una constante de cadena, primero insista en si la cadena
existe en el grupo de constantes de cadena, devuelva la instancia de referencia, si no existe, cree una instancia de la cadena y póngala En la piscina

Ejemplo de código, algunas operaciones de variable local de cadena

String str1 = "abc"; 
String str2 = "abc"; 
String str3 = "abc"; 
String str4 = new String("abc");
String str5 = new String("abc");
String str5 = new String("abc");

Inserte la descripción de la imagen aquí

Puntos y áreas seguras

Punto seguro

Los puntos de seguridad se refieren a ubicaciones específicas en el código. Cuando el subproceso se ejecuta en estas ubicaciones, se determina su estado, de modo que la JVM puede realizar de forma segura algunas operaciones, como GC, etc., por lo que GC no se activa inmediatamente cuando quiere hacerlo , Es necesario esperar a que todos los subprocesos se ejecuten en un punto seguro antes de activarse. Las ubicaciones de estos puntos de seguridad específicos son principalmente las siguientes:

  1. Antes de que vuelva el método
  2. Después de llamar a un método
  3. Donde se lanzó la excepción
  4. Fin del ciclo

Area segura

Safe Point se establece para el subproceso que se está ejecutando.
Si un subproceso está en estado de suspensión o interrupción, no puede responder a la solicitud de interrupción de la JVM y luego ejecutarse al punto seguro. Por lo tanto, la JVM introdujo Safe Region.
Región segura significa que en un fragmento de código, la relación de referencia no cambiará . Es seguro iniciar GC en cualquier lugar de esta área. Cuando el hilo ingresa a la Región Segura, primero marca que ha entrado en la Región Segura, y cuando se despierta para salir de la Región Segura, primero verifica si puede salir. Si el GC se completa, el hilo puede salir, de lo contrario debe esperar hasta que reciba el seguro La señal para irse.

Supongo que te gusta

Origin blog.csdn.net/mlplds/article/details/108700450
Recomendado
Clasificación