Різниця між "на-купі" і "не в купі"


145

Ehcache розповідає про запам’ятовувальну та позагрозову пам’ять. Яка різниця? Які аргументи JVM використовуються для їх налаштування?


Про те , як використовувати від купи пам'яті, див: stackoverflow.com/a/30027374/895245
Чіро Сантіллі郝海东冠状病六四事件法轮功

Відповіді:


169

Навчальний магазин посилається на об'єкти, які будуть присутні в купі Java (а також підпадають під дію GC). З іншого боку, позакладовий магазин посилається на (серіалізовані) об'єкти, якими керує EHCache, але зберігається поза грою (а також не підлягає GC). Оскільки сховищем поза купою продовжує управляти в пам'яті, він трохи повільніше, ніж накопичувач, але все ж швидше, ніж накопичувач диска.

Внутрішні деталі, пов'язані з керуванням та використанням магазину, що не працює, не дуже очевидні у посиланні, розміщеному у запитанні, тому було б розумно перевірити деталі Terracotta BigMemory , яка використовується для управління позадиском. магазин. BigMemory (позабірний магазин) повинен використовуватися, щоб уникнути накладних витрат GC на купу, що має кілька мегабайт або гігабайт. BigMemory використовує адресний простір пам'яті процесу JVM через прямі ByteBuffers , які не підлягають GC на відміну від інших власних об'єктів Java.


18
+1 для згадування прямих байт-буферів для подальшої розвідки;)
Макс

3
Прямі ByteBuffers пропонують доступ до некерованої пам’яті, але самі підлягають GC (на відміну від даних, на які вони вказують). Це важливо, тому що прямий ByteBuffer (вид ByteBuffer.allocateDirect, а не вид MMap) буде зібраний GC, і коли він буде зібраний, Deallocater почне спрацьовувати, ефективно збираючи також некеровану пам'ять.
Nitsan Wakart

Використання Unsafe для розподілу об'єктів виглядає як значно краща ефективність читання та запису через Onheap / DirectByteBuffers / ByteBuffers. ashkrit.blogspot.com/2013/07/…
Джо С

98

від http://code.google.com/p/fast-serialization/wiki/QuickStartHeapOff

Що таке Heap-Offloading?

Зазвичай усіма виділеними не тимчасовими об'єктами керує сміттєзбірник Java. Хоча ВМ робить пристойну роботу, займаючись вивезенням сміття, в певний момент ВМ повинен виконувати так званий «Повний ГК». Повний GC включає сканування повної виділеної Купи, що означає, що паузи / сповільнення GC пропорційні розміру купи програм. Тому не довіряйте будь-якій людині, яка скаже вам: «Пам'ять дешева». У споживанні пам'яті Java шкодить продуктивності. Крім того, ви можете отримати помітні паузи, використовуючи розміри купи> 1 Гбіт. Це може бути неприємно, якщо у вас є якісь фактичні факти, що відбуваються в реальному часі, в кластері або сітці Java-процес може не відповідати і випадати з кластеру.

Однак сьогоднішні серверні програми (часто побудовані на вершинах кривавих фреймворків ;-)) легко вимагають купівлі набагато більше 4 Гбіт.

Одним з рішень цих вимог до пам’яті є «вивантаження» частин об’єктів на купу, яка не є java (безпосередньо виділена з ОС). На щастя, java.nio пропонує класи безпосередньо розподіляти / читати та записувати "некеровані" шматки пам'яті (навіть файли, відображені на пам'ять).

Тож можна виділити велику кількість «некерованої» пам’яті та використовувати її для збереження там об’єктів. Для збереження довільних об'єктів у некерованій пам'яті найбільш життєздатним рішенням є використання серіалізації. Це означає, що додаток серіалізує об'єкти в інтерактивну пам'ять, пізніше об'єкт може бути прочитаний за допомогою десеріалізації.

Розмір купи, яким керує java VM, може бути невеликим, тому паузи GC в мілі, всі раді, робота виконана.

Зрозуміло, що ефективність такого буфера, що випадає, залежить в основному від ефективності реалізації серіалізації. Хороша новина: чомусь FST-серіалізація проходить досить швидко :-).

Зразкові сценарії використання:

  • Кеш сесії в серверній програмі. Використовуйте відображений у пам'яті файл для зберігання гігабайт (неактивних) сеансів користувача. Після входу користувача у вашу програму, ви можете швидко отримати доступ до даних, пов’язаних з користувачем, не маючи справи з базою даних.
  • Кешування результатів обчислень (запити, html-сторінки, ..) (застосовується лише в тому випадку, якщо обчислення повільніші, ніж десеріалізація об'єкта результатів ofc).
  • дуже проста та швидка стійкість за допомогою файлів, відображених на пам'яті

Редагувати: Для деяких сценаріїв можна вибрати більш складні алгоритми збору сміття, такі як ConcurrentMarkAndSweep або G1 для підтримки великих груп (але це також має обмеження понад 16 Гб). Також є комерційний JVM з вдосконаленим «без пауз» GC (Azul).


4
"виділити велику кількість" некерованої "пам'яті і використовувати це для збереження туди об'єктів" - ви не можете зберігати Об'єкти без нагромадження. Ви можете зберігати примітиви, ви можете загортати їх у будь-яку бібліотеку, яка вам подобається, але це не Об'єкти. Дані, які ви розміщуєте в режимі offheap, не мають заголовка об'єкта, ви не можете синхронізувати його, ви не можете посилатися на нього з посилальним полем в іншому об'єкті.
Nitsan Wakart

41

Купа - це місце в пам'яті, де живуть ваші динамічно виділені об’єкти. Якщо ви використовували, newто це на купі. Це на відміну від простору стеку, саме там функціонує стек функцій. Якщо у вас є локальна змінна, то ця посилання є у стеці. Купа Java підлягає вивезенню сміття, і об'єкти можуть бути використані безпосередньо.

Позабагато зберігання EHCache знімає ваш звичайний об’єкт із купи, серіалізує його та зберігає у вигляді байтів у шматку пам'яті, яким управляє EHCache. Це як зберігання на диску, але воно все ще знаходиться в оперативній пам'яті. Об'єкти в такому стані не використовуються безпосередньо, їх слід спочатку дезаріалізувати. Також не підлягає збору сміття.


Це не просто ще в купі, а як серіалізована форма?
Pacerier

1
як це робить його більш ефективним?
Pacerier

2
Є багато способів. Оскільки об'єкти більше не знаходяться на основній купі Java, вони не витрачають час на збирання сміття, вони не фрагментують купу JVM і вони звільняють місце для інших більш використовуваних об'єктів. Крім того, оскільки вони серіалізовані і, швидше за все, не знадобляться в найближчому майбутньому, їх можна стиснути, перемістити по мірі необхідності або навіть передати на екран.
Адам

1
У Hotspot час паузи GC безпосередньо залежить від розміру купи. BigMemory забезпечує цю торгівлю, використовуючи оперативну пам’ять замість купи, щоб мінімізувати паузу GC до мінімуму та уникати вартості IO доступу до диска.
Чандер Шивдасані

17

Коротше кажучи, малюнок

Коротше кажучи, увімкнення / вимкнення Java

pic кредити


Детальна картина

Java On / Off Heap зберігання в деталях

pic кредити


Чи відключається пам'ять купи, керована -xmx? Блакитний - це Old Gen чи off heap?
Himanshu Ahire

Ні. Це невикористаний простір у купі, він заповнюється, коли в купі створюється багато об’єктів.
mrsrinivas

1

JVM нічого не знає про позагромову пам'ять. Ehcache реалізує кеш на дисках, а також кеш пам'яті.


1

Не на 100%; однак, це здається, що купа - це об'єкт або набір виділеного простору (в оперативній пам'яті), який вбудований у функціональність коду або самої Java, або більше ймовірного функціоналу з самого ehcache, а у позагромового Ram є своя система як Ну; однак, це здається, що це на одну величину повільніше, оскільки воно не настільки організовано, це означає, що він може не використовувати купу (маючи на увазі один довгий набір простору оперативної пам’яті), а натомість використовує різні адресні простори, що, ймовірно, робить її трохи менш ефективною.

Тоді, звичайно, наступний нижній рівень - це сам простір на жорсткому диску.

Я не використовую ehcache, тому ви, можливо, не хочете мені довіряти, але це те, що я зібрав з їх документації.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.