Eu conheço o conceito de um pool de constantes e o pool de constantes String usado por JVMs para lidar com literais String. Mas eu não sei qual tipo de memória é usado pela JVM para armazenar literais constantes de String. A pilha ou a pilha? Uma vez que é um literal que não está associado a nenhuma instância, presumo que ele será armazenado na pilha. Mas se não for referido por nenhuma instância, o literal tem que ser coletado pela execução do GC (corrija-me se eu estiver errado), então como isso será tratado se estiver armazenado na pilha?
104
Respostas:
A resposta é tecnicamente nenhuma. De acordo com a Java Virtual Machine Specification, a área para armazenar literais de string está no pool de constantes de tempo de execução . A área de memória do pool constante de tempo de execução é alocada por classe ou por interface, portanto, não está vinculada a nenhuma instância de objeto. O pool de constantes de tempo de execução é um subconjunto da área de método que "armazena estruturas por classe, como o pool de constantes de tempo de execução, dados de campo e método e o código para métodos e construtores, incluindo os métodos especiais usados na inicialização e interface de classe e instância inicialização de tipo ". A especificação VM diz que embora a área do método é logicamente parte do heap, não determina que a memória alocada na área do método esteja sujeita à coleta de lixo ou outros comportamentos que estariam associados às estruturas de dados normais alocadas ao heap.
fonte
Conforme explicado por esta resposta , a localização exata do conjunto de sequências não é especificada e pode variar de uma implementação JVM para outra.
É interessante notar que até o Java 7, o pool estava no espaço permgen do heap no ponto de acesso JVM, mas foi movido para a parte principal do heap desde o Java 7 :
E no Java 8 Hotspot, Permanent Generation foi completamente removido.
fonte
Literais de string não são armazenados na pilha. Nunca. Na verdade, nenhum objeto é armazenado na pilha.
Literais de string (ou mais precisamente, os objetos String que os representam)
sãoarmazenados historicamente em um Heap chamado heap "permgen". (Permgen é a abreviação de geração permanente.)Em circunstâncias normais, os literais String e muitas das outras coisas no heap permgen são "permanentemente" alcançáveis e não são coletados como lixo. (Por exemplo, literais String são sempre alcançáveis a partir dos objetos de código que os utilizam.) No entanto, você pode configurar uma JVM para tentar encontrar e coletar classes carregadas dinamicamente que não são mais necessárias, e isso pode fazer com que literais String sejam coletados como lixo .
ESCLARECIMENTO # 1 - Não estou dizendo que o Permgen não recebe GC. Sim, normalmente quando a JVM decide executar um GC Completo. Meu ponto é que literais de String serão alcançáveis contanto que o código que os usa seja alcançável, e o código será alcançável contanto que o classloader do código seja alcançável, e para os classloaders padrão, isso significa "para sempre".
ESCLARECIMENTO # 2 - Na verdade, o Java 7 e posterior usa o heap regular para conter o pool de strings. Portanto, os objetos String que representam literais String e strings internas estão na verdade no heap regular. (Veja a resposta de @assylias para detalhes.)
Não existe uma "linha tênue". Isto é realmente muito simples:
String
objetos que representam / correspondem a literais de string são mantidos no pool de string.String
objetos que foram criados por umString::intern
chamada são mantidos no string pool.String
objetos NÃO são mantidos no pool de strings.Depois, há a questão separada de onde o pool de strings está "armazenado". Antes do Java 7, era o heap permgen. Do Java 7 em diante, é o heap principal.
fonte
Agrupamento de cordas
String.intern () em Java 6
String.intern () em Java 7
Os valores do pool de strings são coletados como lixo
fonte.
fonte
Como outras respostas explicam, a memória em Java é dividida em duas partes
1. Pilha: Uma pilha é criada por thread e armazena quadros de pilha que, novamente, armazenam variáveis locais e, se uma variável for um tipo de referência, essa variável se refere a um local de memória no heap para o objeto real.
2. Heap: Todos os tipos de objetos serão criados apenas em heap.
A memória heap é novamente dividida em 3 porções
1. Geração jovem: armazena objetos que têm uma vida curta. A própria Geração jovem pode ser dividida em duas categorias Espaço Éden e Espaço Sobrevivente .
2. Antiga Geração: Armazena objetos que sobreviveram a muitos ciclos de coleta de lixo e ainda estão sendo referenciados.
3. Geração permanente: armazena metadados sobre o programa, por exemplo, pool de constantes de tempo de execução.
O pool de constantes de string pertence à área de geração permanente da memória Heap.
Podemos ver o pool de constantes de tempo de execução para nosso código no bytecode usando o
javap -verbose class_name
qual nos mostrará referências de método (#Methodref), objetos de classe (#Class), literais de string (#String)Você pode ler mais sobre isso em meu artigo Como a JVM trata a sobrecarga e a substituição de métodos internamente .
fonte
Às ótimas respostas que já incluímos aqui, quero acrescentar algo que está faltando na minha perspectiva - uma ilustração.
Como você já, a JVM divide a memória alocada para um programa Java em duas partes. um é pilha e outro é pilha . Stack é usado para fins de execução e heap é usado para fins de armazenamento. Nessa memória heap, a JVM aloca alguma memória especialmente destinada a literais de string. Esta parte da memória heap é chamada de pool de constantes de string .
Por exemplo, se você inicializar os seguintes objetos:
Literais de string
s1
es2
irão para o pool de constantes de string, objetos obj1, obj2, obj3 para o heap. Todos eles serão referenciados no Stack.Além disso, observe que "abc" aparecerá no heap e no pool de constantes de string. Por que é
String s1 = "abc"
eString obj1 = new String("abc")
será criado dessa forma? É porqueString obj1 = new String("abc")
cria explicitamente uma instância nova e referencialmente distinta de um objeto String eString s1 = "abc"
pode reutilizar uma instância do pool de constantes de string, se houver uma disponível. Para uma explicação mais elaborada: https://stackoverflow.com/a/3298542/2811258fonte