Работа с поколения на обекти

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

Подобна нужда (да се маркират и уплътнят всички обекти) в JVM може да се нарече неефективна. Тъй като с разпределянето на голям брой обекти техният списък нараства, което води до увеличаване на времето за събиране на боклука. Емпиричният анализ на applicationsта показва, че повечето обекти в Java са краткотрайни.

Областта на куп паметта в JVM е разделена на три секции:

Работа с поколения на обекти

По-младото поколение

Новосъздадените обекти започват в по-младото поколение. По-младото поколение е допълнително разделено на две категории.

  • Eden Space - Всички нови обекти започват оттук, те получават първоначална памет.
  • Survivor Spaces (FromSpace и ToSpace) – Обектите се преместват тук от Eden, след като са преживели един цикъл на събиране на боклука.

Процесът, при който обектите са събрани боклук от по-младото поколение, се нарича второстепенно събитие за събиране на боклук.

Когато пространството на Eden се запълни с предмети, се извършва малко събиране на боклука. Всички мъртви обекти се премахват, а всички живи се преместват в едно от останалите две пространства. Малкият GC също проверява обекти в пространството за оцелели и ги премества в друго (следващо) пространство за оцелели.

Да вземем следната последователност като пример.

  1. В Едем има обекти от двата вида (живи и мъртви).
  2. Появява се малък GC - всички мъртви обекти се премахват от Eden. Всички живи обекти се преместват в пространство-1 (FromSpace). Eden и space-2 вече са празни.
  3. Нови обекти се създават и добавят към Eden. Някои обекти в Eden и Space-1 стават мъртви.
  4. Появява се малък GC - всички мъртви обекти се премахват от Eden и space-1. Всички живи обекти се преместват в пространство-2 (ToSpace). Eden и space-1 са празни.

Така по всяко време едно от местата за оцелели винаги е празно. Когато оцелелите достигнат определен праг за придвижване през пространства за оцелели, те преминават към по-старо поколение.

Можете да използвате флага -Xmn, за да зададете размера на младото поколение .

По-старото поколение

Обектите, които живеят значително време (например по-голямата част от живота на една програма), в крайна сметка стават по-стари обекти - столетници. Известно е още като редовно поколение и съдържа обекти, които са бor оставени в Survivor Spaces за дълго време.

Прагът на жизнения цикъл на даден обект определя колко цикъла на събиране на отпадъци трябва да премине, преди да бъде преместен в по-старото поколение. Процесът, когато обектите се изпращат в боклука от по-старото поколение, се нарича основно събитие за събиране на боклук.

Можете да използвате флаговете -Xms и -Xmx , за да зададете първоначалния и максималния размер на паметта на купчината .

Тъй като Java използва поколение събиране на боклук, колкото повече събития за събиране на боклук преживява даден обект, толкова по-напред се движи в купчината. Той започва в по-младото поколение и в крайна сметка завършва в обикновеното поколение, ако живее достатъчно дълго.

За да разберете промотирането на обекти между пространства и поколения, разгледайте следния пример:

Когато се създава обект, той първо се поставя в райското пространство на младото поколение.

Веднага след като се появи малко събиране на боклук, живите обекти от Eden се преместват във FromSpace. Когато се случи следващото незначително събиране на боклука, живите обекти от Eden и космоса се преместват в ToSpace.

Този цикъл продължава определен брой пъти. Ако обектът все още е "в експлоатация" след тази точка, следващият цикъл на събиране на отпадъци ще го премести в пространството на по-старо поколение.

Постоянно поколение и метапространство

Метаданни като класове и методи се съхраняват в постоянно генериране. JVM го попълва по време на изпълнение въз основа на класовете, използвани от приложението. Класове, които вече не се използват, могат да преминат от постоянно генериране в боклук.

Можете да използвате флаговете -XX:PermGen и -XX:MaxPermGen, за да зададете началния и максималния размер на постоянното генериране .

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

От Java 8 пространството PermGen е заменено от пространството на паметта MetaSpace. Реализацията се различава от PermGen - това пространство на купчина вече се променя автоматично.

Това избягва проблема с липсата на памет на приложението, който възниква поради ограничения размер на пространството на купчината на PermGen. Паметта на метапространството може да бъде събирана за боклук и класовете, които вече не се използват, ще бъдат автоматично изчистени, когато метапространството достигне максималния си размер.