Permanent область пам'яті, java specialist

Насамперед варто зазначити, що дана область не входить в частину купи, що виділяється -Xmx. Для збільшення її обсягу необхідно використовувати параметр -XX: MaxPermSize. Давайте подивимося, що ж зберігається в даній області, і що може призводить до її переповнення.

Метадані про об'єкти

З точки зору java в цій області лежать ті ж об'єкти, що і в основній купі. Тільки це об'єкти певних типів, а саме Class, Method, Field і Constructor. Я можу перерахувати кілька причин зростання числа таких об'єктів.

1. Бібліотеки явно генеруючі байткод

Я знаю як мінімум дві бібліотеки, здатні генерувати байткод: acme і cglib. Так само починаючи з java 6, тепер Ви можете безпосередньо перейти стандартний компілятор. Загалом, раніше теж можна було це зробити через Runtime.getRuntime (). Exec (). Якщо ви нестримно генеруєте байткод і завантажуєте нові класи, то рано чи пізно ви сталкнетесь з OutOfMemoryError.

2. Використання java.lang.reflect.Proxy

Даний стандартний JDK клас генерує і завантажує новий Class. Називаються такі класи як правило Proxy $, де N - ціле число.

3. Бібліотеки неявно генеруючі байткод

Hibernate, Spring, AspectJ і багато інших бібліотеки можуть генерувати класи або використовувати dinamic proxy на льоту.

4. Java Reflection API

Очевидно, що при використанні Reflection створюються об'єкти типу Field і Method. які як уже згадувалося потрапляють в Permanent область. Але зовсім не очевидно, що після багаторазового звернення до якого-небудь полю класу через reflection або виклику його методу, генерується і завантажується новий клас. Справа в тому, що в якості оптимізації, для того щоб в кожен раз не шукати зрушення в таблиці, де лежать дані полів, JVM генерує спеціальні класи, що прискорюють цей процес. Називаються вони як правило GeneratedMethodAccessor, GeneratedFieldAccessor, GeneratedConstructorAccessor де - ціле число. Звичайно ж така поведінка залежить від реалізації JVM і ніяк не специфицируется, але на даний момент HotSpot JVM так робить.

5. Serialization

При використанні стандартної java сериализации використовується reflection. За допомогою нього JVM зчитує поле serialVersionUID. перевіряє наявність методу writeObject. шукає все поля в класі, якщо writeObject НЕ перевизначений, зчитує структуру батька. Рада тут очевидний: не використовуйте інтерфейс Serializable. Як мінімум подивіться рішення Externalizable. Хоча я останнім часом віддаю перевагу Protocol Buffers. як більш крос-платформенне рішення.

Як ви розумієте, RMI активно використовує сериализацию, так що знову отримуємо reflection з усіма наслідками, що випливають звідси ефектами.

Class data sharing (CDS)

У java 5 з'явилася така річ як CDS. Це файл на диску, який є частиною інсталяції JVM, який містить дапм JVM пам'яті, що містить завантажені класи утворюють ядро ​​JVM, тобто ті які напевно JVM довелося б завантажити відразу при старті. Маю таку область, вона відразу мапітся при ініціалізації java машини, тим самим прискорюючи час старту програми. Як ви вже напевно здогадалися, ця сфера теж потрапляє в Permanent область. По суті вона містить всі ті ж об'єкти класів Class, тільки вивантажити їх і очистити пам'ять JVM вже не може.

String pool

Прибирання сміття в PermGen

Коли говорять про збирача сміття, то найчастіше дану область позначають PermGen. За назвою, здавалося б, що об'єкти створені в цій області ніколи не очищаються. Але не всі і не завжди.
Наприклад, пул рядків ніколи не очищається. Так само в разі CDS, Permanent область ділиться на дві: тільки для читання і для читання-запису. Очевидно, що в цьому випадку область тільки для читання не чисто складальником сміття.
Щоб діагностувати проблему завантаження великої кількості класів і перевірити вивантажуються вони чи ні, можна використовувати такі параметри JVM
Щоб включити / відключити вивантаження класів, можна скористатися параметрами
Якщо ви використовуєте low pause збирач сміття (CMS), то щоб включити збірку в PermGen, потрібно виставити два параметра (по крайней мере в java 5 треба було включити обов'язково обидва параметри, інакше не запрацює)

Схожі статті