2010-09-05 2 views
49

Я просто знаю, что не-примитивы (объекты) идут в кучу, а методы идут в стек, но как насчет примитивных переменных?Являются ли примитивы Java в стеке или куче?

--update

Исходя из ответов, я мог бы сказать, что куча может иметь новый стек и кучу для данного объекта? Учитывая, что объект будет иметь примитивные и ссылочные переменные ..?

+1

Каждый поток имеет свой собственный стек, а не каждый объект. Если есть только один поток, то есть только один стек. – Alex

ответ

77

Примитивы, определенные локально, находятся в стеке. Однако, если примитив был определен как часть экземпляра объекта, этот примитив был бы в куче.

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. 
    } 
} 

Что касается обновления:

Объекты не имеют свой собственный стек. В моем примере int y фактически будет частью каждого экземпляра HeapClass. Всякий раз, когда выделяется экземпляр HeapClass (например, new HeapClass()), все переменные-члены HeapClass добавляются в кучу. Таким образом, поскольку экземпляры HeapClass выделяются в куче, int y будет находиться в куче как часть экземпляра HeapClass.

Однако все примитивные переменные, объявленные в теле любого метода, будут находиться в стеке.

Как вы можете видеть в приведенном выше примере, int x находится в стеке, потому что он объявлен в теле метода - не как член класса.

+0

+1 Спасибо! Пожалуйста, рассмотрите мое новое обновление к вопросу. –

+1

Возможно, вы захотите изменить комментарий в своем коде. В тексте вы говорите, что 'x' находится в стеке, но в комментарии говорится куча. – musiKk

+0

Хороший улов. Благодарю. –

19

Все локальные переменные (включая аргументы метода) идут в стек; объекты и все их поля хранятся в куче. Переменные всегда являются примитивами или ссылки на объекты.

Реализации Java могут фактически хранить объекты в куче таким образом, чтобы они все еще соответствовали спецификации. Точно так же локальные переменные могут храниться в регистрах или становиться нечеткими с помощью оптимизации.

+0

+1 Спасибо! Пожалуйста, рассмотрите мое новое обновление к вопросу. –

10

примитивы можно найти в обоих местах.

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 
    } 
} 

кроме вас не должно волноваться, если вы не строите JVM. Действительно умный оптимизатор может решить, что, поскольку Foo, что f указывает на то, что никогда не ускользает от Main, и никогда не переходит к другой функции, можно безопасно выделить его в стеке.

Что касается обновления:

стека и кучи не отличаются тем, что хранится в них, а скорее операции, предусмотренные им. Стек позволяет вам выделить кусок памяти в режиме LIFO, вы не можете освободить кусок, пока все части моложе его не будут освобождены. Это удобно сочетается с тем, как используется стек вызовов. Вы можете поместить что-нибудь в стек, если это нормально, когда эта вещь возвращается, когда ваша функция возвращается. Это оптимизация, так как очень быстро выделять и освобождать из стека, поскольку она поддерживает только то, что используется таким образом. Можно было бы сохранить все локальные переменные для функции в куче в реализации, если захотите. Куча более гибкая и, следовательно, более дорогая в использовании. Неверно было бы сказать, что у объекта есть стек и куча, как я уже сказал, что отличает стек от кучи не то, что в нем, а доступные операции.

+0

+1 Спасибо! Пожалуйста, рассмотрите мое новое обновление к вопросу. –

+0

@Logan: '// f.x, вероятно, находится на куче' -> Вы говорите, что это зависит от реализации JVM? – realPK

7

Примитивные значения выделяются в стеке, если они не являются полями объекта, и в этом случае они переходят в кучу. Стек используется для оценки и выполнения, поэтому нет смысла говорить, что объекты с примитивными полями имеют стек - он по-прежнему считается частью кучи. Даже Stack объекты выделяются в куче.

Смежные вопросы