ti-enxame.com

Java vão para a pilha ou a pilha?

Só sei que os não-primitivos (os objetos) vão para a pilha e os métodos para a pilha, mas e as variáveis ​​primitivas?

- atualização

Com base nas respostas, eu poderia dizer que a pilha pode ter uma nova pilha e pilha para um determinado objeto? Dado que o objeto terá variáveis ​​primitivas e de referência ..?

55
Tom Brito

As primitivas definidas localmente estariam na pilha. No entanto, se uma primitiva fosse definida como parte de uma instância de um objeto, essa primitiva estaria na pilha.

public class Test {
    private static class HeapClass {
        public int y; // When an instance of HeapClass is allocated, this will be on the heap.
    }
    public static void main(String[] args) {
        int x=1; // This is on the stack.
    }
}

Com relação à atualização:

Os objetos não têm sua própria pilha. No meu exemplo, int y Realmente faria parte de cada instância de HeapClass. Sempre que uma instância do HeapClass é alocada (por exemplo, new Test.HeapClass()), todas as variáveis ​​de membro do HeapClass são adicionadas ao heap. Portanto, como instâncias de HeapClass estão sendo alocadas no heap, int y Estaria no heap como parte de uma instância de HeapClass.

No entanto, todas as variáveis ​​primitivas declaradas no corpo de qualquer método seriam na pilha .

Como você pode ver no exemplo acima, int x Está na pilha porque é declarado no corpo de um método - não como membro de uma classe.

85
Jack Edmonds

Todas as variáveis ​​locais (incluindo argumentos do método) vão para a pilha; objetos e todos os seus campos são armazenados na pilha. As variáveis ​​são sempre primitivas ou referências para objetos.

As implementações Java podem realmente armazenar objetos no heap de forma que ainda estejam em conformidade com a especificação. Da mesma forma, variáveis ​​locais podem ser armazenadas em registradores ou tornar-se indistintas através da otimização.

19
Tom Hawtin - tackline

primitivas podem ser encontradas nos dois lugares.

class Foo
{
   public int x;
   public static void Main()
   {
      int y = 3; // y is on the stack
      Foo f = new Foo();  // f.x is probably on the heap
   } 
}

exceto que você realmente não deveria se importar, a menos que esteja construindo uma JVM. Um otimizador muito inteligente pode decidir que, já que o Foo que f aponta para nunca escapa de Main e nunca é passado para outra função, é seguro alocá-lo na pilha.

Com relação à atualização:

A pilha e a pilha não se distinguem pelo que está armazenado nelas, mas pelas operações fornecidas para elas. A pilha permite que você aloque um pedaço de memória da maneira LIFO, você não pode desalocar um pedaço até que todos os pedaços menores do que também tenham sido desalocados. Isso se alinha convenientemente com a forma como uma chamada Você pode colocar qualquer coisa na pilha, desde que seja aceitável que essa coisa desapareça quando sua função retornar.Esta é uma otimização, pois é muito rápido alocar e desalocar uma pilha, pois ela suporta apenas usado dessa maneira. Poderíamos armazenar todas as variáveis ​​locais para uma função no heap em uma implementação, se quiséssemos. O heap é mais flexível e, consequentemente, mais caro de usar. Não seria preciso dizer que um objeto foi uma pilha e uma pilha, como eu disse, o que distingue a pilha da pilha não é o que está nela, mas as operações disponíveis.

10
Logan Capaldo

Os valores primitivos são alocados na pilha, a menos que sejam campos de um objeto; nesse caso, eles vão para a pilha. A pilha é usada para avaliação e execução; portanto, não faz sentido dizer que objetos com campos primitivos têm uma pilha - ainda é considerado parte da pilha. Até objetos Stack são alocados no heap.

7
Mark Cidade