Как известно JVM очень сильно упрощает и автоматизирует работу с памятью. В Java программах программист просто объявляет переменные, даже не беспокоясь о том, как занятая память будет освобождена.
Хотя в некоторых случаях случайным образом можно добиться утечки памяти, где программа просто начнёт пожирать память большими объемами, однако в большинстве случаев все происходит автоматически и без проблем.
Типы распределения памяти
Если говорить в общем, JVM распределяет память на стек (stack) и хип (heap). У каждой программы на Java есть как минимум один родительский процесс, где в каждом процессе располагается обязательно один главный поток. В свою же очередь у каждого потока есть свой стек. В этот стек зачастую попадают все локальные переменные примитивных типов, а также ссылки на данные. Наполняется и освобождается стек автоматически.
Зачем нужен стек (Stack)
Как и было описано ранее, стек (stack) нужен в основном для двух типов данных. Все данные в стеке имеют определенную видимость переменных, ещё называемую областью видимости.
При переполнении стека возникает ошибка java.lang.StackOverFlowError.
Типы памяти в стеке:
- Примитивные типы. Обычно такие типы хранят сами данные, а не ссылки.
- Ссылки на кучу. Сами ссылки занимают минимальный объем памяти, хотя они могут ссылаться на объемные блоки памяти.
Что такое куча (Heap)
Куча (heap) — это основной по объёму хранения данных раздел JVM. В этом разделе хранятся данные классов и объектов.
Как ранее описывалось все ссылки на объекты и классы хранятся в стеке. Любой из потоков может получить доступ к данным, поэтому нужно обязательно побеспокоиться о том, чтобы данные обрабатывались в потокобезопасном режиме.
Сама куча делиться на несколько разделов, которые помогают обрабатывать даннные более рационально.
Когда куча переполняется возникает ошибка java.lang.OutOfMemoryError. В отличии от стека данные автоматически не освобождаются, поэтому если код написан с ошибками можно случайным образом получить утечку памяти, когда программа начнёт потреблять память в значительных объемах.
Разделы кучи (Heap generations)
- Новый раздел (young generation)— в этот раздел попадают все новосозданные объекты.
- Постоянный раздел (permanent generation) — этот раздел отвечает за служебную информацию относительно классов и объектов.
- Старый раздел (old generation) — все данные, которые существуют длительный период времени попадают сюда из нового раздела.