¿Cuánto espacio de memoria ocupa String en Java? ¡Lleve su verificación paso a paso!

Escribir al frente

Recientemente, siempre hago una pregunta: ¿Cuánto espacio de memoria ocupa la clase String en Java? Muchas de las respuestas de mis amigos realmente me dejaron estupefacto. Algunos dijeron que no ocupaban espacio, algunos dijeron 1 byte, algunos dijeron 2 bytes, algunos dijeron 3 bytes, algunos dijeron que no sabían y otros dijeron que no sabían. Lo que es asombroso es que algunas personas dicen que es 2 elevado a 31. Si este es el caso, ¡el espacio de memoria del servidor aún no puede caber en una cadena! Como programadores, no podemos hacer esa broma. Hoy, hablemos de cuánto espacio de memoria ocupa el String en Java.

Los amigos que necesiten más conocimientos de Java y preguntas de la entrevista pueden hacer clic en el enlace de abajo para obtenerlo gratis

Enlace: 1103806531 Contraseña: CSDN

Inserte la descripción de la imagen aquí

La estructura de los objetos Java

Primero, tomemos la estructura del objeto Java en la máquina virtual Aquí, tomemos la máquina virtual HotSpot como ejemplo.

Inserte la descripción de la imagen aquí
Como se puede ver en la imagen de arriba, la estructura del objeto en la memoria incluye principalmente las siguientes partes:

  • Marca de palabra (campo marcado): La parte de marca de palabra del objeto ocupa 4 bytes y su contenido es una serie de bits de marca, como los bits de marca de bloqueo de peso ligero, los bits de marca de bloqueo de polarización, etc.
  • Puntero de Klass (puntero de objeto de clase): el tamaño del puntero de objeto de clase también es de 4 bytes, y la ubicación a la que apunta es la dirección de memoria del objeto de clase correspondiente al objeto (su objeto de metadatos correspondiente)
  • Los datos reales del objeto: incluye todas las variables miembro del objeto, y su tamaño está determinado por el tamaño de cada variable miembro. Por ejemplo, byte y boolean son 1 byte, short y char son 2 bytes e int y float son 4 Byte, long y double son 8 bytes, la referencia es 4 bytes
  • Alineación: la última parte es alinear los bytes rellenos, que se rellenan con 8 bytes.

En otras palabras:

  • Encabezado del objeto: 8 bytes (guarde la información de clase del objeto, ID, estado en la máquina virtual)
  • Datos primitivos de Java: como int, float, char y otros tipos de datos
  • Referencia: 4 bytes
  • Relleno

Tipo de cadena en Java

Espacio ocupado por String vacío

Aquí, tomamos Java8 como ejemplo para ilustrarlo. Primero, echemos un vistazo a las variables miembro en la clase String.

/** The value is used for character storage. */
private final char value[];
 
/** Cache the hash code for the string */
private int hash; // Default to 0
 
/** use serialVersionUID from JDK 1.0.2 for interoperability */
private static final long serialVersionUID = -6849794470754667710L;

Las matrices también son objetos en Java, por lo que las matrices también tienen encabezados de objeto. Por lo tanto, el espacio ocupado por una matriz es el espacio ocupado por el encabezado del objeto más la longitud de la matriz más la referencia de la matriz, es decir, 8 + 4 + 4 = 16 bytes.

Entonces, podemos obtener el espacio de memoria ocupado por un objeto String vacío, como se muestra a continuación.

对象头(8 字节)+ 引用 (4 字节 )  + char 数组(16 字节)+ 1int4字节)+ 1long8字节)= 40 字节

Entonces, amigos míos, ¿son correctas sus respuestas?

Espacio ocupado por String no vacío

Si la longitud de la cadena String es mayor que 0, también podemos obtener la fórmula de cálculo para la memoria ocupada por String, como se muestra a continuación.

40 + 2 * n

Entre ellos, n es la longitud de la cuerda.

Aquí, algunos amigos pueden preguntar, ¿por qué es 40 + 2 n? Esto se debe a que 40 es el espacio de memoria ocupado por una cadena vacía. Como ya dijimos anteriormente, la clase String realmente almacena datos en la matriz de variables miembro char [] y un tipo char en la matriz char [] Los datos ocupan 2 bytes de espacio, por lo que solo los datos en la cadena ocuparán 2 n (n es la longitud de la cadena) bytes de espacio, más los 40 bytes ocupados por la cadena vacía, Finalmente, el espacio de almacenamiento ocupado por una cadena es: 40 + 2 * n (n es la longitud de la cadena).

Nota: La fórmula 40 + 2 * n se puede considerar como una fórmula general para calcular cuánto espacio de memoria ocupa el objeto String.

Por lo tanto, cuando se usa una gran cantidad de objetos String en el código, se debe considerar el uso real de la memoria.

Conclusión de la verificación

A continuación, verificaremos nuestras conclusiones anteriores juntos. Primero, cree una clase UUIDUtils para generar un UUID de 32 bits, como se muestra a continuación.

package io.mykit.binghe.string.test;

import java.util.UUID;

/**
 * @author binghe
 * @version 1.0.0
 * @description 生成没有-的UUID
 */
public class UUIDUtils {
    
    
    public static String getUUID(){
    
    
        String uuid = UUID.randomUUID().toString();
        return uuid.replace("-", "");
    }
}

A continuación, cree una clase TestString, cree una matriz con una longitud de 4000000 en el método main () y luego llene la matriz con cadenas UUID, como se muestra a continuación.

package io.mykit.binghe.string.test;

import java.util.UUID;

/**
 * @author binghe
 * @version 1.0.0
 * @description 测试String占用的内存空间
 */
public class TestString{
    
    
    public static void main(String[] args){
    
    
         String[] strContainer = new String[4000000];
        for(int i = 0; i < 4000000; i++){
    
    
            strContainer[i] = UUIDUtils.getUUID();
            System.out.println(i);
        }
        //防止程序退出
        while(true){
    
    

        }
    }
}

Aquí, hay 4000000 cadenas de caracteres, y la longitud de cada cadena de caracteres es 32, por lo que el espacio de memoria ocupado por almacenar los datos de la cadena es: (40 + 32 2) 4000000 = 416000000 bytes, que es aproximadamente igual a 416 MB.

Usamos la herramienta de análisis de memoria Jprofiler para el análisis:

Inserte la descripción de la imagen aquí
Como puede ver, el resultado de usar la herramienta de análisis de memoria Jprofiler es: 321MB + 96632KB, que es aproximadamente igual a 417MB. La razón por la que los resultados obtenidos al usar la herramienta de análisis de memoria Jprofiler son más grandes que nuestros cálculos es porque durante la ejecución real del programa, se generarán algunas cadenas dentro del programa, ¡y estas cadenas también ocuparán espacio en la memoria! !

Por tanto, los resultados obtenidos mediante el uso de la herramienta de análisis de memoria Jprofiler cumplieron con nuestras expectativas.

Al final

También he compilado un conjunto completo de tutoriales en video para arquitectos y materiales sistemáticos sobre Java, que incluyen puntos de conocimiento básicos de Java, temas de entrevistas y las últimas preguntas reales y libros electrónicos de Internet durante 20 años. ¡Los amigos que lo necesiten pueden hacer clic en el enlace de abajo para obtenerlo gratis!

Enlace: 1103806531 Contraseña: CSDN

Inserte la descripción de la imagen aquí
Inserte la descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/XingXing_Java/article/details/109250697
Recomendado
Clasificación