Piscina constante de cadena en Java
Hay dos formas de creación de objetos de cadena en Java. Uno es una forma literal, como String Str = "Droid"; y el otro es un método estándar para construir objetos que usan nuevos, como String Str = New String ("Droid");. A menudo usamos estos dos métodos al escribir código, especialmente el método literal. Sin embargo, estas dos implementaciones en realidad tienen algunas diferencias en el rendimiento y el uso de la memoria. Todo esto se debe al hecho de que el JVM mantiene una memoria especial para reducir la creación repetida de objetos de cadena, que es una piscina constante de cadena o grupo literal de cadena.
Cómo funciona
Cuando se crea un objeto de cadena en el formulario literal en el código, el JVM primero verificará el literal. Si hay una referencia a un objeto de cadena con el mismo contenido en el grupo de constantes de cadena, se devolverá la referencia. De lo contrario, se creará el nuevo objeto de cadena, y luego la referencia se colocará en el grupo constante de cadena y se devolverá la referencia.
Dar un ejemplo
Forma de creación literal
Cadena str1 = "droide";
JVM detecta este literal, aquí creemos que no existe ningún objeto con contenido. El JVM no puede encontrar el objeto de cadena con contenido de droides a través del grupo de constantes de cadena, por lo que creará este objeto de cadena y luego colocará la referencia del objeto que acaba de crear en el grupo constante de cadena y devolverá la referencia a la variable STR1.
Si hay un código como este siguiente
Cadena str2 = "droide";
Del mismo modo, el JVM aún necesita detectar este literal. Al buscar el grupo de constante de cadena, el JVM descubrió que el contenido es el objeto de cadena "droide", por lo que devuelve la referencia del objeto de cadena existente a la variable ST2. Tenga en cuenta que los nuevos objetos de cadena no se recrearán aquí.
Verifique si Str1 y Str2 apuntan al mismo objeto, podemos usar este código
System.out.println (str1 == str2);
El resultado es verdadero.
Crear con nuevo
Cadena str3 = new String ("Droid");
Cuando usamos nuevos para construir objetos de cadena, se crearán nuevos objetos de cadena independientemente de si hay referencias a objetos con el mismo contenido en el grupo de constante de cadena. Así que usemos el siguiente código para probarlo.
Cadena str3 = new String ("Droid");
System.out.println (str1 == str3);
El resultado es falso como pensamos, lo que indica que las dos variables apuntan a diferentes objetos.
interno
Para el objeto de cadena creado con el nuevo arriba, si desea agregar una referencia al grupo de constantes de cadena, puede usar el método interno.
Después de llamar al interno, primero verifique si hay una referencia al objeto en el grupo constante de cadena. Si existe, devuelva esta referencia a la variable, de lo contrario, la referencia se agregará y se devolverá a la variable.
Cadena str4 = str3.intern ();
System.out.println (str4 == Str1);
El resultado de salida es verdadero.
Problemas difíciles
¿Prerrequisitos?
El requisito previo para implementar grupos constantes de cadena es que los objetos de cadena en Java son inmutables, lo que puede garantizar de manera segura que múltiples variables compartan el mismo objeto. Si el objeto de cadena en Java es variable, y una operación de referencia cambia el valor del objeto, otras variables también se verán afectadas, obviamente esto no es razonable.
Referencia u objeto
Esta pregunta es más común cuando un grupo constante de cadena se almacena en una referencia o un objeto. La cadena constante de la piscina almacena referencias de objetos, no objetos. En Java, los objetos se crean en la memoria del montón.
La verificación de la actualización, muchos comentarios recibidos también están discutiendo este tema, y simplemente lo verifico. Verificar el entorno
22: 18: 54-Androidyue ~/Videos $ Cat/etc/OS-ReleaseName = FedoraVersion = "17 (Beefy Miracle)" Id = Fedoraversion_id = 17Pretty_Name = "Fedora 17 (Beefy Milagro) "ansi_color =" 0; 34 "cpe_name =" cpe:/o: fedoraproject: Fedora: 17 "22: 19: 04-androidyue ~/videos $ java -versionJava versión" 1.7.0_25 "Openjdk Runtime Entorno (Fedora-2.3.12.1.fc17-x86_64) VM (compilación 23.7-B01, modo mixto)
Idea de verificación: el siguiente programa Java lee un archivo de video de 82 m de tamaño y realiza operaciones de pasante en forma de cadena.
22: 01: 17 -Androidyue ~/Videos $ ll -lh | Grep Why_To_learn.Mp4-RW-RW-R--. 1 Androidyue Androidyue 82m 20 de octubre de 2013 Why_to_learn.mp4
Código de verificación
import java.io.bufferedReader; import java.io.filenotfoundException; import java.io.filereader; import java.io.ioException; public class testMain {private static string fileContent; public static void main (string [] args) {fileContent = readFilEToString (args [0]); if (null! = fileContent) {fileContent = fileContent.Intern (); System.out.println ("no nulo"); }} cadena estática privada readFilEToString (archivo de cadena) {bufferedReader lector = null; intente {lector = new BufferedReader (new FileReader (archivo)); StringBuffer buff = new StringBuffer (); Línea de cadena; while ((línea = lector.readline ())! = null) {buff.append (línea); } return buff.ToString (); } catch (FileNotFoundException e) {E.PrintStackTrace (); } catch (ioException e) {E.PrintStackTrace (); } Finalmente {if (null! = lector) {try {reader.close (); } catch (ioException e) {E.PrintStackTrace (); }}} return null; }}Dado que el grupo constante de cadena existe en la generación permanente en la memoria del montón, es adecuado antes de Java 8. Verificamos estableciendo una generación permanente de un valor pequeño. Si el objeto de cadena existe en el grupo constante de cadena, se debe lanzar un error de espacio Java.lang.OUTOFMEMORYERROR PermGen.
Java -xx: PermSize = 6m testMain ~/videos/why_to_learn.mp4
Ejecutar el programa de prueba no arroja OOM, pero esto no puede probar que se almacene como un objeto o una referencia.
Pero esto al menos prueba que el objeto de contenido real Char [] de la cadena no se almacena en el grupo constante de cadena. En este caso, no es tan importante que el grupo constante de cadena almacene referencias a objetos de cadena o objetos de cadena. Pero las personas todavía tienden a almacenar referencias.
Pros y contras
La ventaja de la agrupación constante de cadena es reducir la creación de cadenas del mismo contenido y guardar espacio de memoria.
Si tiene que decir las desventajas, es sacrificar el tiempo de computación de la CPU para intercambiar espacio. El tiempo de cálculo de la CPU se usa principalmente para encontrar si hay referencias a objetos con el mismo contenido en el grupo constante de cadena. Sin embargo, su implementación interna es hashtable, por lo que el costo de cálculo es bajo.
¿Reciclaje GC?
Debido a que el grupo constante de cadena contiene una referencia al objeto de cadena compartida, ¿significa esto que estos objetos no se pueden reciclar?
En primer lugar, los objetos compartidos en la pregunta son generalmente más pequeños. Hasta donde he verificado, había tal problema en versiones anteriores, pero con la introducción de referencias débiles, este problema debería desaparecer en la actualidad.
Con respecto a este tema, puede obtener más información sobre este artículo. Cordas internadas: Glosario Java
Usar pasante?
El requisito previo para usar interno es que sabe que realmente necesita usarlo. Por ejemplo, tenemos un registro de millones aquí, donde un cierto valor del registro es California, EE. UU. Muchas veces. No queremos crear millones de tales objetos de cadena. Podemos usar pasante para mantener solo una copia en la memoria. Para una comprensión más profunda de los pasantes, consulte el análisis en profundidad de String#pasante.
¿Hay siempre excepciones?
¿Sabe que el siguiente código creará varios objetos de cadena y guardará varias referencias en el grupo de constantes de cadena?
Cadena test = "A" + "B" + "C";
La respuesta es que solo se crea un objeto y solo se guarda una referencia en el grupo constante. Usamos la descompilación de Javap y lo echamos un vistazo.
17:02 $ Javap -C TestInternedPoolgcCCompilado de "TestInternedPoolgc.Java" TestInternedPoolGC extiende java.lang.object {public testInternedPoolgc (); Código: 0: Aload_0 1: Invokespecial #1; // método java/lang/objeto. "<Init>" :() V 4: returnpublic static void main (java.lang.string []) lanza java.lang.exception; Código: 0: LDC #2; // String ABC 2: Store_1 3: Return¿Lo has visto? De hecho, durante el período de compilación, estos tres literales se han sintetizado en uno. Esta es en realidad una optimización que evita la creación de objetos de cadena redundantes y no tiene problemas de costura de cadenas. Para las costuras de cadena, puede ver los detalles de Java: costuras de cadena.
Lo anterior es una compilación de la información sobre los grupos constantes de cadena en Java. Continuaremos agregando información relevante en el futuro. ¡Gracias por su apoyo para este sitio!