По-перше, у чому різниця між Пермським простором та Кучевим простором (Що і як JVM вирішує використовувати кожен простір пам'яті)?
По-друге, але найголовніше, яке співвідношення буде рекомендовано для стандартного додатку Java типу MVC?
Відповіді:
У купі зберігаються всі об’єкти, створені вашою програмою Java. Вміст купи контролюється за допомогою збирача сміття, який звільняє пам’ять від купи, коли ви перестаєте використовувати об’єкт (тобто коли більше немає посилань на об’єкт).
Це на відміну від стека , який зберігає примітивні типи, такі як ints та chars, і, як правило, це локальні змінні та значення функції, що повертаються. Це не зібране сміття.
Завивка простір відноситься до спеціальної частини купи. Див. Цю відповідь SO для пояснення: Що таке проміжна космос?
-XX:MaxPermSize=256m
щоб встановити розмір місця для хімічної завивки на 256 МБ.
Особисто я б не вважав PermGen особливою частиною купи.
Я б набагато віддав перевагу думці про кучу як про область пам'яті, призначену для зберігання екземплярів об’єктів, а про PermGen як про область, призначену для зберігання визначень класів. Як результат, життєвий цикл купи пов’язаний із додатком, тоді як життєвий цикл PermGen пов’язаний із JVM.
Один із найкращих прикладів, чому програма та її JVM можуть мати різний життєвий цикл, - це контейнер Java EE. На сервері додатків програми можна розгортати та розгортати без перезапуску сервера. Під час розгортання (або передислокації) легко звільнити всі екземпляри об’єктів, тобто простір купи, але досить складно очистити всі класи, завантажені цим додатком, з PermGen, оскільки на деякі класи все ще може посилатися JVM.
Одним з таких випадків є драйвери, що витікають . Коли програма розгорнута, драйвер JDBC завантажується та реєструється в DriverManager. Коли ця програма не розгорнута, DriverManager живе і зберігає посилання на драйвер, оригінальний завантажувач класу та все завантажене цим завантажувачем класу. В результаті створюється витік пам'яті в PermGen, але це не є виною в управлінні пам'яттю програми.
Це правда, що JVM, такі як JRocket, взагалі не мають PermGen, все зберігається в купі. Тільки в такому контексті ви можете назвати PermGen "особливою частиною" купи. Навіть тоді нам все одно слід розглядати PermGen і купу по-різному, оскільки вони мають дуже різне призначення і у них дуже різні типи витоків пам'яті.
Оновлення : У JDK 8 Oracle PermGen замінено на "Метапростір", і тепер воно офіційно є частиною купи. Нам більше не потрібно буде налаштовувати PermGen.
Ви НЕ можете давати імена виділеній пам'яті в купі.
Це означає, що int x
(його назва) виділено у стеку. Ви можете отримати вказівник за його назвою, тому вказівник знаходиться в стеку. Ви не можете дістати об’єкт за його назвою, оскільки він не має назви. Доступ до (безіменного) об’єкта має здійснюватися за його покажчиком.