String Constant Pool em Java
Existem duas formas de criação de objetos de string em Java. Um é uma forma literal, como String str = "Droid"; e o outro é um método padrão de construção de objetos usando novos, como String str = new String ("Droid");. Frequentemente usamos esses dois métodos ao escrever código, especialmente o método literal. No entanto, essas duas implementações realmente têm algumas diferenças no desempenho e no uso da memória. Tudo isso se deve ao fato de a JVM manter uma memória especial para reduzir a criação repetida de objetos de string, que é um pool constante de string ou um pool literal literal.
Como funciona
Quando um objeto de string é criado na forma literal do código, a JVM verifica primeiro o literal. Se houver uma referência a um objeto String com o mesmo conteúdo no pool constante da string, a referência será retornada. Caso contrário, o novo objeto String será criado e, em seguida, a referência será colocada no pool constante de string e a referência será retornada.
Dê um exemplo
Formulário de criação literal
String str1 = "Droid";
A JVM detecta esse literal, aqui pensamos que não existe um objeto com conteúdo Droid. A JVM não consegue encontrar o objeto String com conteúdo dróide através do pool constante da string, para criar esse objeto String e, em seguida, colocará a referência do objeto que você acabou de criar no pool constante da string e retornará a referência à variável str1.
Se houver um código como este próximo
String str2 = "Droid";
Da mesma forma, a JVM ainda precisa detectar esse literal. Ao pesquisar o pool constante de string, a JVM descobriu que o conteúdo é "dRoid", existe objeto de string, para que retorne a referência do objeto String existente à variável str2. Observe que novos objetos de string não serão recriados aqui.
Verifique se Str1 e Str2 apontam para o mesmo objeto, podemos usar este código
System.out.println (str1 == str2);
O resultado é verdadeiro.
Criar com novo
String str3 = new String ("Droid");
Quando usamos novos para construir objetos de string, novos objetos de string serão criados, independentemente de haver referências a objetos com o mesmo conteúdo no pool constante da string. Então, vamos usar o seguinte código para testá -lo.
String str3 = new String ("Droid");
System.out.println (str1 == str3);
O resultado é falso como pensamos, indicando que as duas variáveis apontam para diferentes objetos.
Intern
Para o objeto String criado com o novo acima, se você deseja adicionar uma referência ao pool constante de string, poderá usar o método Intern.
Depois de ligar para o estagiário, verifique se há uma referência ao objeto no pool constante de string. Se houver, retorne essa referência à variável; caso contrário, a referência será adicionada e devolvida à variável.
String str4 = str3.intern ();
System.out.println (str4 == str1);
O resultado da saída é verdadeiro.
Problemas difíceis
Pré -requisitos?
O pré -requisito para a implementação de pools constantes de string é que os objetos de string em Java são imutáveis, o que pode garantir com segurança que várias variáveis compartilhem o mesmo objeto. Se o objeto String no Java for variável e uma operação de referência alterar o valor do objeto, outras variáveis também serão afetadas, obviamente isso não é razoável.
Referência ou objeto
Esta questão é mais comum quando um pool constante de string é armazenado em uma referência ou um objeto. A string constante piscina armazena referências de objetos, não objetos. Em Java, os objetos são criados na memória da heap.
Atualizar verificação, muitos comentários recebidos também estão discutindo esse problema e eu simplesmente o verificar. Verifique o ambiente
22: 18: 54-Androidyue ~/Videos $ CAT/etc/OS-RELEASENAME = fedorAversion = "17 (Miracle e carpachoso)" Id = fedorAversion_id = 17pretty_name = "Fedora 17 (carnuda MIRACLE) "ANSI_COLOR =" 0; 34 "CPE_NAME =" CPE:/O: Fedoraproject: Fedora: 17 "22: 19: 04-Androidyue ~/Videos $ Java-VersionJava Version" 1.7.0_25 "Ambiente de RunTime (fedora-2.3.2.1.1.1.1.1.1.0_25 ~ Servidor VM (Build 23.7-B01, modo misto)
Ideia de verificação: O programa Java a seguir lê um arquivo de vídeo de 82m e executa operações de estagiário na forma de uma string.
22: 01: 17 -Androidyue ~/Videos $ ll -lh | Grep Why_to_Learn.MP4-RW-RW-R--. 1 Androidyue Androidyue 82m 20 de outubro de 2013 Why_to_learn.mp4
Código de verificação
importar java.io.bufferedReader; importar java.io.filenotfoundException; importar java.io.fileReader; importar java.io.ioException; classe pública testmain {private estático string fileContent; public static void main (string [] args) {FileContent = readFileToString (args [0]); if (null! = FileContent) {FileContent = FileContent.intern (); System.out.println ("não nulo"); }} private static string readFileToString (arquivo de string) {bufferredreader leitor = null; tente {reader = new BufferredReader (new FileReader (arquivo)); StringBuffer buff = new StringBuffer (); Linha de string; while ((line = reader.readline ())! = null) {buff.append (line); } return buff.toString (); } catch (filenotfoundException e) {e.printStackTrace (); } catch (ioexception e) {e.printStackTrace (); } finalmente {if (null! = leitor) {try {reader.close (); } catch (ioexception e) {e.printStackTrace (); }}} retornar nulo; }}Como o pool constante de cordas existe na geração permanente na memória da heap, ela é adequada antes do Java 8. Verificamos definindo uma geração permanente de um pequeno valor. Se o objeto String existir no pool constante da string, um erro de espaço java.lang.outOfMemoryError deve ser lançado.
java -xx: PermSize = 6m testmain ~/videos/why_to_learn.mp4
A execução do programa de prova não joga OOM, mas isso não pode provar que é armazenado como um objeto ou uma referência.
Mas isso pelo menos prova que o objeto de conteúdo real char [] da string não é armazenado no pool constante de string. Nesse caso, não é tão importante que a string constante do pool armazena referências a objetos de string ou objetos da string. Mas os indivíduos ainda tendem a armazenar referências.
Prós e contras
A vantagem do agrupamento constante de string é reduzir a criação de cordas do mesmo conteúdo e salvar o espaço de memória.
Se você precisa dizer as desvantagens, é para sacrificar o tempo de computação da CPU para trocar espaço. O tempo de cálculo da CPU é usado principalmente para descobrir se há referências a objetos com o mesmo conteúdo no pool constante de string. No entanto, sua implementação interna é hashtável, portanto o custo de cálculo é baixo.
Reciclagem do GC?
Como o pool constante da string mantém uma referência ao objeto String compartilhado, isso significa que esses objetos não podem ser reciclados?
Primeiro de tudo, os objetos compartilhados na questão geralmente são menores. Até onde eu verifiquei, houve de fato um problema nas versões anteriores, mas com a introdução de referências fracas, esse problema deve desaparecer no momento.
Em relação a esse problema, você pode aprender mais sobre este artigo. Strings internados: Glossário de Java
Usar estagiário?
O pré -requisito para o uso do Intern é que você sabe que realmente precisa usá -lo. Por exemplo, temos um registro de milhões aqui, onde um certo valor do registro é a Califórnia, EUA, muitas vezes. Não queremos criar milhões desses objetos de string. Podemos usar o Intern para manter apenas uma cópia na memória. Para uma compreensão mais aprofundada do estagiário, consulte a análise aprofundada do String#Intern.
Sempre existem exceções?
Você sabia que o código a seguir criará vários objetos de string e salvará várias referências no pool constante de string?
String test = "A" + "B" + "C";
A resposta é que apenas um objeto é criado e apenas uma referência é salva no pool constante. Usamos a decomposição do Javap e damos uma olhada nela.
17:02 $ javap -C TestInternedPoolgCCompiled de "TestInterNedPoolgc.java" Public Class TestInterNedPoolgc estende java.lang.object {public testInternedpoolgc (); Código: 0: Aload_0 1: Invokespecial #1; // método java/lang/objeto. Código: 0: LDC #2; // string abc 2: store_1 3: retornarVocê viu isso? De fato, durante o período de compilação, esses três literais foram sintetizados em um. Na verdade, isso é uma otimização que evita criar objetos redundantes de string e não possui problemas de costura de string. Para costura de cordas, você pode visualizar os detalhes do Java: costura de string.
O exposto acima é uma compilação das informações sobre pools constantes de string em Java. Continuaremos a adicionar informações relevantes no futuro. Obrigado pelo seu apoio a este site!