Разница между «на куче» и «на куче»


146

Ehcache говорит о памяти в куче и вне кучи. В чем разница? Какие аргументы JVM используются для их настройки?


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

Ответы:


169

Хранилище в куче относится к объектам, которые будут присутствовать в куче Java (а также подчиняться GC). С другой стороны, хранилище вне кучи относится к (сериализованным) объектам, которые управляются EHCache, но хранятся вне кучи (и также не подлежат GC). Поскольку хранилище вне кучи продолжает управляться в памяти, оно немного медленнее, чем хранилище в куче, но все же быстрее, чем хранилище дисков.

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


18
+1 за упоминание прямых ByteBuffers для дальнейшего исследования;)
Макс

3
Direct ByteBuffers предлагают доступ к неуправляемой памяти, но сами подчиняются GC (в отличие от данных, на которые они указывают). Это важно, потому что GC будет собирать прямой ByteBuffer (вид ByteBuffer.allocateDirect, а не вид MMap), и когда он собирается, его Deallocater запускается, эффективно собирая также неуправляемую память.
Ницан Вакарт

Использование Unsafe для выделения объектов похоже на значительно лучшую производительность чтения и записи по сравнению с Onheap / DirectByteBuffers / ByteBuffers. ashkrit.blogspot.com/2013/07/…
Джо К,

98

от http://code.google.com/p/fast-serialization/wiki/QuickStartHeapOff

Что такое Куча-Разгрузка?

Обычно все не временные объекты, которые вы размещаете, управляются сборщиком мусора Java. Хотя виртуальная машина выполняет достойную работу по сбору мусора, в определенный момент виртуальная машина должна выполнить так называемый «полный сборщик мусора». Полный GC включает сканирование всей выделенной кучи, что означает, что паузы / замедления GC пропорциональны размеру кучи приложений. Поэтому не верьте никому, кто говорит вам: «Память дешева». В Java потребление памяти вредит производительности. Кроме того, вы можете получить заметные паузы, используя размеры кучи> 1 Гб. Это может быть неприятно, если у вас есть какие-то вещи, происходящие почти в реальном времени, в кластере или сетке процесс Java может перестать отвечать и выпадать из кластера.

Однако сегодняшним серверным приложениям (часто созданным поверх раздуваемых фреймворков ;-)) легко требуются кучи, намного превышающие 4 Гб.

Одним из решений этих требований к памяти является «разгрузка» частей объектов в кучу, отличную от Java (непосредственно выделяемую из ОС). К счастью, java.nio предоставляет классы для прямого выделения / чтения и записи «неуправляемых» фрагментов памяти (даже файлов, отображаемых в память).

Таким образом, можно выделить большие объемы «неуправляемой» памяти и использовать ее для сохранения объектов там. Для сохранения произвольных объектов в неуправляемую память наиболее жизнеспособным решением является использование сериализации. Это означает, что приложение сериализует объекты в оперативную память, позже объект может быть прочитан с помощью десериализации.

Размер кучи, управляемый виртуальной машиной Java, может быть небольшим, поэтому GC-паузы находятся в миллисекундах, все довольны, работа выполнена.

Понятно, что производительность такого буфера вне кучи зависит в основном от производительности реализации сериализации. Хорошая новость: почему-то FST-сериализация довольно быстрая :-).

Примеры сценариев использования:

  • Кеш сессии в серверном приложении. Используйте отображенный в памяти файл для хранения гигабайт (неактивных) пользовательских сеансов. Как только пользователь входит в ваше приложение, вы можете быстро получить доступ к пользовательским данным, не имея дело с базой данных.
  • Кэширование результатов вычислений (запросов, html страниц, ..) (применимо, только если вычисления медленнее, чем десериализация объекта результата c).
  • очень простое и быстрое использование файлов с отображенной памятью

Редактировать: для некоторых сценариев можно выбрать более сложные алгоритмы сборки мусора, такие как ConcurrentMarkAndSweep или G1, для поддержки больших куч (но это также имеет свои пределы, превышающие кучу 16 ГБ). Существует также коммерческая JVM с улучшенным GC (Azul) без пауз.


4
«выделять большие объемы« неуправляемой »памяти и использовать ее для сохранения объектов там» - вы не можете сохранить объекты без контроля. Вы можете хранить примитивы, вы можете обернуть их в любую библиотеку, которая вам нравится, но это не объекты. Данные, которые вы помещаете в автономный каталог, не имеют заголовка объекта, вы не можете синхронизировать его, вы не можете ссылаться на него с помощью поля ссылки в каком-либо другом объекте.
Ницан Вакарт

41

Куча - это место в памяти, где живут ваши динамически размещенные объекты. Если вы использовали, newто это в куче. Это в отличие от стекового пространства, где живет стек функций. Если у вас есть локальная переменная, эта ссылка находится в стеке. Куча Java подвергается сборке мусора, и объекты можно использовать напрямую.

Хранилище вне кучи EHCache извлекает обычный объект из кучи, сериализует его и сохраняет его в виде байтов в порции памяти, которой управляет EHCache. Это все равно что хранить его на диске, но он все еще находится в оперативной памяти. Объекты не могут быть непосредственно использованы в этом состоянии, они должны быть сначала десериализованы. Также не подлежит сборке мусора.


Разве это не все еще в куче, а в виде сериализованной формы?
Pacerier

1
как это делает его более эффективным?
Pacerier

2
Есть много способов. Поскольку объекты больше не находятся в основной куче Java, они не тратят время сборщика мусора, они не фрагментируют кучу JVM и освобождают место для других более часто используемых объектов. Кроме того, поскольку они сериализованы и, вероятно, не нужны в ближайшем будущем, они могут быть сжаты, перемещены по мере необходимости или даже выгружены на диск.
Адам

1
В Hotspot время паузы в GC напрямую зависит от размера кучи. BigMemory обеспечивает этот компромисс, используя оперативную память вместо кучи, чтобы свести к минимуму паузу в GC и избежать затрат на ввод-вывод в доступ к диску.
Чандер Шивдасани

18

Вкратце

Короче говоря, Java On / Off

фото кредитов


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

Java Вкл / Выкл Куча хранилища в деталях

фото кредитов


Отключена ли память кучи от -xmx? Синий - это Старый Генерал или не в кучу?
Химаншу Ахире

Нет. Это неиспользуемое пространство в куче, оно будет заполнено, когда много объектов создано в куче.
Миссринивас

1

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


1

Не 100%; однако, похоже, что куча - это объект или набор выделенного пространства (в ОЗУ), который встроен в функциональность кода либо в саму Java, либо, более вероятно, в функциональность самого ehcache, а Ram вне кучи - это собственная система как хорошо; однако, это звучит так, как будто это на одну величину медленнее, поскольку оно не организовано, а это означает, что он может не использовать кучу (имеется в виду один длинный набор пространства памяти RAM), а вместо этого использует разные адресные пространства, что, вероятно, делает его немного менее эффективным.

Тогда, конечно, следующий уровень ниже - это само пространство на жестком диске.

Я не использую ehcache, так что вы можете не захотеть мне доверять, но это то, что я собрал из их документации.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.