A pilha e a pilha Java em Java divide a memória em dois tipos: um é a memória da pilha e o outro é a memória da pilha.
Alguns tipos básicos de variáveis definidos nas funções e variáveis de referência dos objetos são alocados na memória da pilha da função. Quando uma variável é definida em um bloco de código, o Java aloca espaço de memória para a variável na pilha. Quando o escopo da variável exceder o escopo da variável, o Java libera automaticamente o espaço de memória alocado para a variável e o espaço de memória pode ser usado separadamente imediatamente.
A memória da pilha é usada para armazenar objetos e matrizes criados pela New. A memória alocada na pilha é gerenciada pelo coletor automático de lixo da máquina virtual Java. Depois que uma matriz ou objeto é gerada na pilha, uma variável especial pode ser definida na pilha. O valor dessa variável é igual ao primeiro endereço da matriz ou objeto na memória da heap. Essa variável especial na pilha se torna uma variável de referência para a matriz ou objeto. No futuro, você pode usar a variável de referência na memória da pilha no programa para acessar a matriz ou objeto na pilha. A variável de referência é equivalente a um alias ou nome de código para a matriz ou objeto.
Variáveis de referência são variáveis comuns. Quando definido, a memória é alocada na pilha. As variáveis de referência são liberadas fora do escopo quando o programa é executado. A própria matriz e objeto é alocada na pilha. Mesmo que o programa seja executado fora do bloco de código, onde as instruções que usam novas para gerar a matriz e o objeto estão localizados, a memória da pilha ocupada pela matriz e o próprio objeto não será liberado. A matriz e o objeto só tornam -se lixo quando não há variável de referência apontando para ele, e não podem mais ser usados, mas ainda ocupa a memória e são liberados pelo coletor de lixo em um momento incerto. Essa também é a principal razão pela qual Java ocupa mais memória. De fato, variáveis no ponto de pilha para variáveis na memória da heap, que é o ponteiro em Java!
Pilha e pilha em java
O Java divide a memória em dois tipos: um é a memória da pilha e o outro é a memória da heap.
1. A pilha e a pilha são os dois lugares usados pelo Java para armazenar dados na RAM. Ao contrário do C ++, o Java gerencia automaticamente pilhas e pilhas, e os programadores não podem configurar pilhas ou montes diretamente.
2. A vantagem da pilha é que a velocidade de acesso é mais rápida que a pilha, perdendo apenas os registros localizados diretamente na CPU. Mas a desvantagem é que o tamanho e a vida útil dos dados na pilha devem ser determinísticos e não ter flexibilidade. Além disso, os dados da pilha podem ser compartilhados. A vantagem do heap é que ele pode alocar dinamicamente o tamanho da memória e a vida útil não precisa ser contada ao compilador com antecedência. O coletor de lixo da Java coletará automaticamente os dados que não são mais usados. Mas a desvantagem é que a memória deve ser alocada dinamicamente em tempo de execução, a velocidade de acesso é mais lenta.
3. Existem dois tipos de dados em Java.
Um são os tipos básicos (tipos primitivos), existem 8 tipos, ou seja, int, curto, longo, byte, flutuante, duplo, booleano, char (nota,
Não há tipo básico de string). Este tipo de definição é definido por um formulário como int a = 3; longo b = 255l; e é chamado de variável automática. Vale ressaltar que a variável automática contém valores literais, não instâncias da classe, ou seja, não é referências à classe, e não há classe aqui. Por exemplo, int a = 3; Aqui está uma referência apontando para o tipo int,
Aponte para o valor literal de 3. Devido ao tamanho desses valores literais, a vida útil desses valores literais pode ser conhecida (esses valores literais são fixados em um bloco de programa e, após o bloco do programa sair, o valor do campo desaparece).
Por uma questão de velocidade, existe na pilha.
Além disso, um recurso especial muito importante da pilha é que os dados na pilha podem ser compartilhados. Suponha que definimos ao mesmo tempo:
int a = 3;
int b = 3;
O compilador primeiro processos int a = 3; Primeiro, ele criará uma referência à variável A na pilha e descobrirá se existe um endereço com um valor literal de 3. Se não for encontrado, ele abrirá um endereço com o valor literal de 3 e depois apontará para o endereço 3. Então processará int b = 3; Depois de criar a variável de referência de B, como já existe um valor literal de 3 na pilha, B é diretamente apontado para o endereço de 3. Dessa maneira, A e B ambos apontam para 3 ao mesmo tempo.
É particularmente importante observar que essa referência literal é diferente da dos objetos de classe. Supondo que as referências de dois objetos de classe apontem para um objeto ao mesmo tempo, se uma variável de referência de objeto altera o estado interno do objeto, a outra variável de referência do objeto reflete imediatamente essa alteração. Em vez disso, modificar seu valor por meio de uma referência literal não fará com que outro valor seja alterado de acordo. Como no exemplo acima, depois de definirmos os valores de A e B, deixe A = 4; Em seguida, B não será igual a 4, ou igual a 3. Dentro do compilador, quando a = 4 for encontrado, ele se pesquisará se existe um valor literal de 4 na pilha. Caso contrário, reabre o endereço para armazenar o valor de 4; Se já existe, aponte diretamente a este endereço. Portanto, a mudança no valor a não afetará o valor b.
Outro tipo são dados da classe de embalagem, como número inteiro, string, dupla etc. que envolvem os tipos de dados básicos correspondentes. Todos esses dados de classe existem na pilha. O Java usa a instrução new () para exibir o compilador e só cria dinamicamente conforme necessário em tempo de execução, por isso é mais flexível, mas a desvantagem é que ele leva mais tempo.
Em Java, existem seis lugares diferentes onde os dados podem ser armazenados:
1. Registre -se. Esta é a área de armazenamento mais rápida porque está localizada em um local diferente das de outras áreas de armazenamento - o processador. No entanto, o número de registros é extremamente limitado; portanto, os registros são alocados pelo compilador de acordo com os requisitos. Você não pode controlá -lo diretamente, nem pode sentir nenhum sinal da existência do registro no programa.
2. Pilha. Localizado em RAM de uso geral, mas com seu "ponteiro de pilha", você pode obter suporte do processador. Se o ponteiro da pilha descer, a nova memória será alocada; Se ele se mover, essa memória será libertada. Esta é uma maneira rápida e eficiente de alocar armazenamento, perdendo apenas para registros. Ao criar um programa, o compilador Java deve saber o tamanho exato e o ciclo de vida de todos os dados armazenados na pilha, porque deve gerar o código correspondente para mover o ponteiro da pilha para cima e para baixo. Essa restrição limita a flexibilidade do programa; portanto, embora alguns dados do JA VA sejam armazenados na pilha - especialmente referências de objetos, os objetos Java não são armazenados nele.
3. Heap. Um pool de memória universal (também existe na RAM) para armazenar os chamados objetos Java. A vantagem da pilha é que o compilador não precisa saber quantas áreas de armazenamento para alocar a partir da pilha, nem precisa saber quanto tempo os dados armazenados durarão na pilha. Portanto, há grande flexibilidade na alocação de armazenamento na pilha. Quando você precisa criar um objeto, você só precisa escrever uma linha simples de código no novo. Ao executar essa linha de código, ela armazenará e alocará automaticamente na pilha. Obviamente, o código correspondente deve ser pago por essa flexibilidade. Leva mais tempo para alocar o armazenamento com a pilha do que armazená -lo com a pilha.
4. Armazenamento estático. "estático" aqui significa "em uma posição fixa". O armazenamento estático armazena dados que sempre existiram quando o programa está em execução. Você pode usar a palavra -chave estática para identificar que um elemento específico de um objeto é estático, mas o próprio objeto Java nunca é armazenado no espaço de armazenamento estático.
5. Armazenamento constante. Os valores constantes geralmente são armazenados diretamente dentro do código do programa, e é seguro fazê -lo porque nunca serão alterados. Às vezes, em um sistema incorporado, a própria constante é separada de outras partes; portanto, neste caso, é opcional colocá -lo na ROM.
6. Armazenamento não-RAM. Se os dados sobreviverem completamente fora do programa, ele poderá ser deixado sem qualquer controle do programa e pode existir quando o programa não estiver em execução.
Em termos de velocidade, há um relacionamento da seguinte maneira:
Registro <pilha <heap <outro
"A passagem acima é extraída de" Thinking in Java ""
Pergunta 1:
String str1 = "abc"; String str2 = "abc"; System.out.println (str1 == str2); //verdadeiro
Pergunta 2:
String str1 = new String ("ABC"); String str2 = new String ("ABC"); System.out.println (str1 == str2); // false Pergunta 3:
String S1 = "JA"; String S2 = "VA"; String s3 = "java"; String s4 = s1 + s2; System.out.println (s3 == s4); // false System.out.println (s3.equals (s4)); // true
Alguns tipos básicos de variáveis definidos nas variáveis de função e referência do objeto são alocados na memória da pilha da função.
Quando uma variável é definida em um bloco de código, o Java aloca espaço de memória para essa variável na pilha. Quando o escopo da variável exceder a variável, o Java libera automaticamente o espaço de memória alocado para a variável e o espaço de memória pode ser usado separadamente imediatamente.
A memória da pilha é usada para armazenar objetos e matrizes criados pela New.
A memória alocada na pilha é gerenciada pelo coletor automático de lixo da Java Virtual Machine.
Depois que uma matriz ou objeto é gerada na pilha, uma variável especial pode ser definida na pilha, para que o valor dessa variável na pilha seja igual ao primeiro endereço da matriz ou objeto na memória da pilha, e a variável na pilha se torna uma variável de referência para a matriz ou objeto.
Uma variável de referência é equivalente a um nome dado a uma matriz ou objeto. Você pode usar as variáveis de referência na pilha no programa para acessar a matriz ou objeto na pilha.
Especificamente: a pilha e a pilha são ambos os locais usados pelo Java para armazenar dados na RAM. Ao contrário do C ++, o Java gerencia automaticamente pilhas e pilhas, e os programadores não podem configurar pilhas ou montes diretamente.
A pilha Java é uma área de dados de tempo de execução, da qual os objetos alocam espaço. Esses objetos são estabelecidos por meio de instruções como New, NewArray, Anewarray e MultianeWarray. Eles não exigem que o código do programa seja explicitamente liberado. A pilha é responsável pela coleta de lixo. A vantagem do heap é que ele pode alocar dinamicamente o tamanho da memória, e a vida útil não precisa ser contada ao compilador com antecedência, porque aloca dinamicamente a memória no tempo de execução. O coletor de lixo da Java coletará automaticamente os dados que não são mais usados. Mas a desvantagem é que, porque precisa alocar dinamicamente a memória em tempo de execução, a velocidade de acesso é mais lenta.
A vantagem da pilha é que a velocidade de acesso é mais rápida que a pilha, perdendo apenas para os registros, e os dados da pilha podem ser compartilhados. Mas a desvantagem é que o tamanho e a vida útil dos dados na pilha devem ser determinísticos e não ter flexibilidade. A pilha armazena principalmente alguns tipos básicos de variáveis (, int, curto, longo, byte, flutuação, dupla, booleana, char) e alças de objetos.
Um recurso especial muito importante da pilha é que os dados existentes na pilha podem ser compartilhados. Suponha que definimos ao mesmo tempo:
int a = 3;
int b = 3;
O compilador primeiro processos int a = 3; Primeiro, ele criará uma referência na pilha com uma variável A e descobrirá se há um valor de 3 na pilha. Se não for encontrado, ele armazenará 3 e depois apontará a a 3. Então processará int b = 3; Depois de criar a variável de referência de B, porque já existe um valor de 3 na pilha, B é apontado diretamente para 3. Dessa maneira, A e B ambos apontam para 3 ao mesmo tempo. Neste momento, se A = 4 estiver definido novamente; Em seguida, o compilador procurará novamente se há um valor 4 na pilha. Caso contrário, armazene 4 e ponto A a 4; Se já existir, aponte diretamente para este endereço. Portanto, a mudança no valor a não afetará o valor b. Deve -se notar que esse compartilhamento de dados é diferente do compartilhamento de referências de dois objetos apontando para um objeto ao mesmo tempo, porque neste caso a modificação de A não afetará B, é feito pelo compilador, que é propício ao espaço para economizar. Uma variável de referência de objeto modifica o estado interno desse objeto e afetará outra variável de referência de objeto.
String é um dados de embalagem especial. Pode ser usado:
String str = new String ("ABC"); String str = "abc"; Existem duas formas para criar. O primeiro é usar o novo () para criar um novo objeto, que será armazenado na pilha. Um novo objeto é criado toda vez que é chamado.
O segundo tipo é primeiro criar uma variável STR para o objeto da classe String na pilha e, em seguida, descubra se há "ABC" armazenado na pilha. Caso contrário, armazene "ABC" na pilha e deixe o STR apontar para "ABC". Se já houver "ABC", deixe o STR apontar para "ABC".
Ao comparar se os valores da classe são iguais, use o método iguals (); Ao testar se as referências das duas classes de wrapper apontam para o mesmo objeto, use == e use o exemplo abaixo para ilustrar a teoria acima.
String str1 = "abc"; String str2 = "abc"; System.out.println (str1 == str2); //verdadeiro
Pode -se observar que o STR1 e o STR2 apontam para o mesmo objeto.
String str1 = new String ("ABC"); String str2 = new String ("ABC"); System.out.println (str1 == str2); // false O novo método é gerar objetos diferentes. Gerar um de cada vez.
Portanto, da segunda maneira, várias seqüências "ABC" são criadas e há apenas um objeto na memória. Este método de escrita é benéfico e salva o espaço da memória. Ao mesmo tempo, pode melhorar a velocidade de execução do programa até certo ponto, porque a JVM decidirá automaticamente se é necessário criar um novo objeto com base na situação real dos dados na pilha. Para o código de string str = new String ("ABC");, novos objetos são criados na pilha, independentemente de seus valores de sequência serem iguais ou não, seja necessário criar novos objetos, aumentando assim a carga do programa.
Por outro lado, observe: quando definimos uma classe usando um formato como String str = "ABC";, sempre tomamos como certo que criamos um objeto STR da classe String. (Não necessariamente, porque se não houver antecipadamente, será criado. Esta é a criação do objeto. Se já houver, aponte para o objeto original)! O objeto pode não ter sido criado! E talvez apenas aponte para um objeto que foi criado anteriormente. Somente através do método novo () podemos garantir que um novo objeto seja criado sempre. Devido à natureza imutável da classe String, quando a variável da string precisa transformar frequentemente seu valor, considere usar a classe StringBuffer para melhorar a eficiência do programa.