Java куча и стек - PullRequest
       7

Java куча и стек

2 голосов
/ 10 января 2012

Я хочу снова изучать Java, потому что я оставил это несколько лет назад.Читая книгу, у меня возникли проблемы с пониманием того, как Java выделяет память в куче и в стеке.

Это то, что я понял, - я попытаюсь рассказать об этом на примерах.

class TestA {
    int a;

    void methodA(int b) {
        a = b;
    }

    int getA() {
        return a;
    }
}

Это пример класса, чтобы показать другую ситуацию.И это мое главное:

int b = 3;

TestA obj = new TestA();
obj.methodA(b);
obj.getA();

Так что же происходит?


## BEGIN

STACK - возьмите немного памяти для основногофункция

HEAP - пусто


## int b = 3

STACK - [возьмем немного памяти для основной функции -> здесь мыиметь b]

HEAP - [пусто]


## TestA obj = новый TestA ()

STACK - [занять немного памятидля основной функции -> здесь у нас есть b и ссылка на TestA]

HEAP - [взять немного памяти для int a]


## obj.methodA (b);

STACK - [взять немного памяти для основной функции -> здесь у нас есть b и ссылка на TestA]

HEAP - [взять немного памяти для int a] И [другая память для метода A]


## выполнить метод A (int b)

STACK - [взять немного памяти для основной функции -> здесь мы имеем b иссылка на TestA] И [взять память для methodA () -> здесь мы использовали b в этой функции]

HEAP - [взять немного памяти для int a] И [еще одну память для метода A]


У нас есть:

  • поле объекта И экземпляра (примитив или нет) вкуча
  • функция и значение области в стеке

Это правильно?

Ответы [ 3 ]

2 голосов
/ 10 января 2012

Вначале помните, что в куче будет также экземпляр Class для вашего класса (и нескольких других).

Re:

## TestA obj =новый TestA ()

STACK - [взять немного памяти для основной функции -> здесь у нас есть b и ссылка на TestA]

HEAP - [взять немного памяти для int a]

a будет в куче, а не в стеке, как часть памяти, выделенной для экземпляра TestA.b и obj находятся в стеке, распределяются при входе в main (э-э, я думаю, именно тогда это происходит; возможно, JVM не резервирует для них место в стеке, пока не встретит объявления впрограммный поток, но там мы попадаем во внутреннее пространство JVM).Куча также содержит экземпляр TestA.(Помните, что obj, переменная, совершенно отличается от того, на что она указывает [экземпляр TestA]; каждая из этих вещей занимает память.)

Также помните, что в стеке будет возвращатьсяадреса для вызовов функций.Например, когда main вызывает methodA, адрес, к которому должна вернуться JVM при возврате methodA, также находится в стеке.

Различные структуры стека также будут выделены для обработки исключений.

Вышесказанное в основном теоретическое, ум.JVM могут выполнять оптимизацию, и они это делают (HotSpot - это полностью оптимизирующая JVM).@Voo указывает, например, что JVM могут поместить объекты в стек, если обнаружат, что могут (например, когда экземпляр объекта используется только в методе, а анализ байт-кода JVM показывает, что там невозможнобыть выдающейся ссылкой на него при выходе из метода).

1 голос
/ 10 января 2012

Хотя Java указана как стековая машина, на практике она не реализована таким образом, поэтому в реальных JVM размер стека изменяется только при выходе или входе в метод.

Куча никогда не бывает пустой - она ​​включает в себя такие объекты, как Object.class и другие, которые создаются загрузчиком классов начальной загрузки до запуска main.

Все действия, такие как new ClassName(...), выделяют пространство в куче *, а все объявления переменных (int x, Object ref) указывают, что пространство должно быть выделено в стеке при вводе функции включения **.

* - см. Предостережение об оптимизации на https://stackoverflow.com/a/8690592/20394
** - опять же оптимизация может привести к совместному использованию слотов стека.

0 голосов
/ 20 августа 2012

По умолчанию все объекты размещены в куче. Однако есть оптимизация компилятора, которая позволяет объектам размещаться в стеке (или избегать размещения всех вместе). В частности, анализ побега позволяет это в Java 6.

...