Что такое стек и куча java

Основные принципы программирования: стек и куча

Что такое стек и куча java. Смотреть фото Что такое стек и куча java. Смотреть картинку Что такое стек и куча java. Картинка про Что такое стек и куча java. Фото Что такое стек и куча java

Мы используем всё более продвинутые языки программирования, которые позволяют нам писать меньше кода и получать отличные результаты. За это приходится платить. Поскольку мы всё реже занимаемся низкоуровневыми вещами, нормальным становится то, что многие из нас не вполне понимают, что такое стек и куча, как на самом деле происходит компиляция, в чём разница между статической и динамической типизацией, и т.д. Я не говорю, что все программисты не знают об этих понятиях — я лишь считаю, что порой стоит возвращаться к таким олдскульным вещам.

Сегодня мы поговорим лишь об одной теме: стек и куча. И стек, и куча относятся к различным местоположениям, где происходит управление памятью, но стратегия этого управления кардинально отличается.

Стек — это область оперативной памяти, которая создаётся для каждого потока. Он работает в порядке LIFO (Last In, First Out), то есть последний добавленный в стек кусок памяти будет первым в очереди на вывод из стека. Каждый раз, когда функция объявляет новую переменную, она добавляется в стек, а когда эта переменная пропадает из области видимости (например, когда функция заканчивается), она автоматически удаляется из стека. Когда стековая переменная освобождается, эта область памяти становится доступной для других стековых переменных.

Из-за такой природы стека управление памятью оказывается весьма логичным и простым для выполнения на ЦП; это приводит к высокой скорости, в особенности потому, что время цикла обновления байта стека очень мало, т.е. этот байт скорее всего привязан к кэшу процессора. Тем не менее, у такой строгой формы управления есть и недостатки. Размер стека — это фиксированная величина, и превышение лимита выделенной на стеке памяти приведёт к переполнению стека. Размер задаётся при создании потока, и у каждой переменной есть максимальный размер, зависящий от типа данных. Это позволяет ограничивать размер некоторых переменных (например, целочисленных), и вынуждает заранее объявлять размер более сложных типов данных (например, массивов), поскольку стек не позволит им изменить его. Кроме того, переменные, расположенные на стеке, всегда являются локальными.

В итоге стек позволяет управлять памятью наиболее эффективным образом — но если вам нужно использовать динамические структуры данных или глобальные переменные, то стоит обратить внимание на кучу.

Куча — это хранилище памяти, также расположенное в ОЗУ, которое допускает динамическое выделение памяти и не работает по принципу стека: это просто склад для ваших переменных. Когда вы выделяете в куче участок памяти для хранения переменной, к ней можно обратиться не только в потоке, но и во всем приложении. Именно так определяются глобальные переменные. По завершении приложения все выделенные участки памяти освобождаются. Размер кучи задаётся при запуске приложения, но, в отличие от стека, он ограничен лишь физически, и это позволяет создавать динамические переменные.

27–29 декабря, Онлайн, Беcплатно

Вы взаимодействуете с кучей посредством ссылок, обычно называемых указателями — это переменные, чьи значения являются адресами других переменных. Создавая указатель, вы указываете на местоположение памяти в куче, что задаёт начальное значение переменной и говорит программе, где получить доступ к этому значению. Из-за динамической природы кучи ЦП не принимает участия в контроле над ней; в языках без сборщика мусора (C, C++) разработчику нужно вручную освобождать участки памяти, которые больше не нужны. Если этого не делать, могут возникнуть утечки и фрагментация памяти, что существенно замедлит работу кучи.

В сравнении со стеком, куча работает медленнее, поскольку переменные разбросаны по памяти, а не сидят на верхушке стека. Некорректное управление памятью в куче приводит к замедлению её работы; тем не менее, это не уменьшает её важности — если вам нужно работать с динамическими или глобальными переменными, пользуйтесь кучей.

Заключение

Вот вы и познакомились с понятиями стека и кучи. Вкратце, стек — это очень быстрое хранилище памяти, работающее по принципу LIFO и управляемое процессором. Но эти преимущества приводят к ограниченному размеру стека и специальному способу получения значений. Для того, чтобы избежать этих ограничений, можно пользоваться кучей — она позволяет создавать динамические и глобальные переменные — но управлять памятью должен либо сборщик мусора, либо сам программист, да и работает куча медленнее.

Источник

Память стека и пространство кучи в Java

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

1. введение

Чтобы запустить приложение оптимальным образом, JVM делит память на память стека и кучи. Всякий раз, когда мы объявляем новые переменные и объекты, вызываем новый метод, объявляем Строку или выполняем аналогичные операции, JVM выделяет память для этих операций либо из памяти стека, либо из пространства кучи.

В этом уроке мы обсудим эти модели памяти. Мы рассмотрим некоторые ключевые различия между ними, как они хранятся в оперативной памяти, какие функции они предлагают и где их использовать.

2. Стековая память в Java

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

Доступ к этой памяти осуществляется в порядке “Последний вход-первый выход” (LIFO). Всякий раз, когда вызывается новый метод, создается новый блок в верхней части стека, содержащий значения, характерные для этого метода, такие как примитивные переменные и ссылки на объекты.

Когда метод завершает выполнение, соответствующий кадр стека сбрасывается, поток возвращается к вызывающему методу, и пространство становится доступным для следующего метода.

2.1. Основные характеристики стековой памяти

Помимо того, что мы обсуждали до сих пор, ниже приведены некоторые другие особенности стековой памяти:

3. Пространство кучи в Java

Эти объекты имеют глобальный доступ и могут быть доступны из любой точки приложения.

Эта модель памяти далее разбивается на более мелкие части, называемые поколениями, это:

Эти различные части также обсуждаются в этой статье – Разница между JVM, JRE и JDK.

3.1. Основные характеристики кучной памяти Java

Помимо того, что мы обсуждали до сих пор, ниже приведены некоторые другие особенности пространства кучи:

4. Пример

Основываясь на том, что мы узнали до сих пор, давайте проанализируем простой Java-код и оценим, как здесь управляется память:

Давайте проанализируем это шаг за шагом:

При вводе метода main() в памяти стека будет создано пространство для хранения примитивов и ссылок этого метода

Вызов параметризованного конструктора Person(int, String) из main() выделит дополнительную память поверх предыдущего стека. Это будет хранить:

Это распределение объясняется на этой диаграмме:

Источник

Стек, очередь и куча

На рисунке вы можете видеть обобщенную модель организации памяти компьютера.

Что такое стек и куча java. Смотреть фото Что такое стек и куча java. Смотреть картинку Что такое стек и куча java. Картинка про Что такое стек и куча java. Фото Что такое стек и куча java

Стек — это область памяти, которую вы, как программист, не контролируете никоим образом. В неё записываются переменные и информация, которые создаются в результате вызова любых функций. Когда функция заканчивает работу, то вся информация о ее вызов и ее переменные удаляются из стека автоматически.

Что такое стек и куча java. Смотреть фото Что такое стек и куча java. Смотреть картинку Что такое стек и куча java. Картинка про Что такое стек и куча java. Фото Что такое стек и куча java

Но важнее даже не это, а то, что стек — это структура данных, которая работает по принципу «последним пришел — первым ушел» (last in first out, LIFO). На лекции Дэвид предложил представление стека, как стопки подносов в столовой. Поднос, который попал в стопку последним, новый клиент столовой возьмет в первую очередь.

Над стеком можно осуществлять две операции: push (занесение данных) и pop (изъятие данных).

Что такое стек и куча java. Смотреть фото Что такое стек и куча java. Смотреть картинку Что такое стек и куча java. Картинка про Что такое стек и куча java. Фото Что такое стек и куча java

Пример реализации стека языке С приведен ниже. В этом примере, стек — это просто массив строк, имеет определенную емкость (CAPACITY), и текущий размер (size):

Что такое стек и куча java. Смотреть фото Что такое стек и куча java. Смотреть картинку Что такое стек и куча java. Картинка про Что такое стек и куча java. Фото Что такое стек и куча java

Для реализации операции pop, необходимо проверить, не пустой стек, уменьшить текущий размер на единицу и вернуть элемент.

Что такое стек и куча java. Смотреть фото Что такое стек и куча java. Смотреть картинку Что такое стек и куча java. Картинка про Что такое стек и куча java. Фото Что такое стек и куча java

Очередь

Очередь (queue) — это структура данных, которая напоминает обычную очередь. То есть, в отличие от стека, она работает по принципу «первым пришел — первым ушел» (first in first out, FIFO).

Что такое стек и куча java. Смотреть фото Что такое стек и куча java. Смотреть картинку Что такое стек и куча java. Картинка про Что такое стек и куча java. Фото Что такое стек и куча java

Для очереди определены две операции: добавление элемента в конец очереди (enqueue) и изъятие элемента с начала очереди (dequeue).

Что такое стек и куча java. Смотреть фото Что такое стек и куча java. Смотреть картинку Что такое стек и куча java. Картинка про Что такое стек и куча java. Фото Что такое стек и куча java

В примере объявлена очередь, которая, по сути, представляет собой массив строк:

Чтобы реализовать операцию enqueue, необходимо убедиться, что очередь, не переполнена, добавить элемент в конец очереди и увеличить текущий размер на единицу.

Что такое стек и куча java. Смотреть фото Что такое стек и куча java. Смотреть картинку Что такое стек и куча java. Картинка про Что такое стек и куча java. Фото Что такое стек и куча java

Чтобы реализовать операцию dequeue, надо убедиться, что очередь не пуста, увеличить head на единицу, уменьшить текущий размер и вернуть первый элемент очереди.

Что такое стек и куча java. Смотреть фото Что такое стек и куча java. Смотреть картинку Что такое стек и куча java. Картинка про Что такое стек и куча java. Фото Что такое стек и куча java

Куча и переполнение буфера

Куча (heap) — область памяти, которую контролируют непосредственно программисты. Над которой вы, как программисты, получаете непосредственный контроль. Память здесь выделяется в результате вызова функции malloc.

Более глубокие знания о стеке и куче вам пока не понадобятся. Вы их получите позже, если захотите изучать программирование и компьютерные науки глубже.

Буфер — это массив определенной длины, расположенный в памяти. Переполнение буфера (buffer overflow) возникает, если мы пытаемся записать в него больше данных, чем предусмотрено размером этого массива. С помощью переполнения буфера злоумышленник может записать опасный код в память компьютера.

Источник

Что такое Heap и Stack память в Java?

В Java есть такие понятия как Heap и Stack память. Сегодня мы узнаем разницу между ними и зачем они нужны. Как всегда, сначала в теории и затем на практике разберем эту сложную тему.

Java Heap память

Java Heap (куча) используется Java Runtime для выделения памяти под объекты и JRE классы. Создание нового объекта также происходит в куче. Здесь работает сборщик мусора: освобождает память путем удаления объектов, на которые нет каких-либо ссылок. Любой объект, созданный в куче, имеет глобальный доступ и на него могут ссылаться с любой части приложения.

Stack память в Java

Стековая память в Java работает по схеме LIFO (Последний-зашел-Первый-вышел). Всякий раз, когда вызывается метод, в памяти стека создается новый блок, который содержит примитивы и ссылки на другие объекты в методе. Как только метод заканчивает работу, блок также перестает использоваться, тем самым предоставляя доступ для следующего метода.
Размер стековой памяти намного меньше объема памяти в куче.

Давайте рассмотрим отличия стековой памяти и кучи на примере простой программы.

На картинке ниже представлена память стека и кучи для программы выше

Что такое стек и куча java. Смотреть фото Что такое стек и куча java. Смотреть картинку Что такое стек и куча java. Картинка про Что такое стек и куча java. Фото Что такое стек и куча java

А теперь рассмотри шаги выполнения нашей программы:

Разница между Stack и Heap памятью в Java

На основании приведенных выше объяснений, мы можем легко подытожить следующие различия между Heap и Stack памятью в Java.

Вот и все, что нужно знать о Stack и Heap памяти в Java. Следите за обновлениями в разделе Полезности.

Источник

Развеиваем мифы об управлении памятью в JVM

Что такое стек и куча java. Смотреть фото Что такое стек и куча java. Смотреть картинку Что такое стек и куча java. Картинка про Что такое стек и куча java. Фото Что такое стек и куча java

Структура памяти JVM

Сначала давайте посмотрим на структуру памяти JVM. Эта структура применяется начиная с JDK 11. Вот какая память доступна процессу JVM, она выделяется операционной системой:

Что такое стек и куча java. Смотреть фото Что такое стек и куча java. Смотреть картинку Что такое стек и куча java. Картинка про Что такое стек и куча java. Фото Что такое стек и куча java

Это нативная память, выделяемая ОС, и её размер зависит от системы, процессор и JRE. Какие области и для чего предназначены?

Куча (heap)

Здесь JVM хранит объекты и динамические данные. Это самая крупная область памяти, в ней работает сборщик мусора. Размером кучи можно управлять с помощью флагов Xms (начальный размер) и Xmx (максимальный размер). Куча не передаётся виртуальной машине целиком, какая-то часть резервируется в качестве виртуального пространства, за счёт которого куча может в будущем расти. Куча делится на пространства «молодого» и «старого» поколения.

Стеки потоков исполнения

Метапространство

Кеш кода

Здесь компилятор Just In Time (JIT) хранит скомпилированные блоки кода, к которым приходится часто обращаться. Обычно JVM интерпретирует байткод в нативный машинный код, однако код, скомпилированный JIT-компилятором, не нужно интерпретировать, он уже представлен в нативном формате и закеширован в этой области памяти.

Общие библиотеки

Здесь хранится нативный код для любых общих библиотек. Эта область памяти загружается операционной системой лишь один раз для каждого процесса.

Использование памяти JVM: стек и куча

Теперь давайте посмотрим, как исполняемая программа использует самые важные части памяти. Воспользуемся нижеприведённым кодом. Он не оптимизирован с точки зрения корректности, так что игнорируйте проблемы вроде ненужных промежуточных переменных, некорректных модификаторов и прочего. Его задача — визуализировать использование стека и кучи.

Здесь вы можете увидеть, как исполняется вышеприведённая программа и как используются стек и куча:

Управление памятью JVM: сборка мусора

Давайте разберёмся с автоматическим управлением кучей, которое играет очень важную роль с точки зрения производительности приложения. Когда программа пытается выделить в куче больше памяти, чем доступно (в зависимости от значения Xmx ), мы получаем ошибки нехватки памяти.

JVM управляет куче с помощью сборки мусора. Чтобы освободить место для создания нового объекта, JVM очищает память, занятую потерянными объектами, то есть объектами, на которые больше нет прямых или опосредованных ссылок из стека.

Что такое стек и куча java. Смотреть фото Что такое стек и куча java. Смотреть картинку Что такое стек и куча java. Картинка про Что такое стек и куча java. Фото Что такое стек и куча java

Сборщик мусора в JVM отвечает за:

Сборщик мусора Mark & Sweep

JVM использует отдельный поток демона, который работает в фоне для сборки мусора. Этот процесс запускается при выполнении определённых условий. Сборщик Mark & Sweep обычно работает в два этапа, иногда добавляют третий, в зависимости от используемого алгоритма.

Что такое стек и куча java. Смотреть фото Что такое стек и куча java. Смотреть картинку Что такое стек и куча java. Картинка про Что такое стек и куча java. Фото Что такое стек и куча java

JVM предлагает на выбор несколько разных алгоритмов сборки мусора, и в зависимости от вашего JDK может быть ещё больше вариантов (например, сборщик Shenandoah в OpenJDK). Авторы разных реализаций стремятся к разным целям:

Сборщики в JDK 11

Процесс сборки мусора

Вне зависимости от того, какой выбран сборщик, в JVM используется два вида сборки — младший и старший сборщик.

Младший сборщик

Он поддерживает чистоту и компактность пространства молодого поколения. Запускается тогда, когда JVM не может получить в раю необходимую память для размещения нового объекта. Изначально все области кучи пусты. Рай заполняется первым, за ним область выживших, и в конце хранилище.

Здесь вы можете увидеть процесс работы этого сборщика:

Старший сборщик

Следит за чистотой и компактностью пространства старого поколения (хранилищем). Запускается при одном из таких условий:

Заключение

Мы рассмотрели структуру и управление памятью JVM. Это не исчерпывающая статья, мы не говорили о многих более сложных концепциях и способах настройки под особые сценарии использования. Подробнее вы можете почитать здесь.

Но для большинства JVM-разработчиков (Java, Kotlin, Scala, Clojure, JRuby, Jython) этого объёма информации будет достаточно. Надеюсь, теперь вы сможете писать более качественный код, создавать более производительные приложения, избегая различных проблем с утечкой памяти.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *