Использование огромных страниц и DirectByteBuffer в java hotspot jvm в Linux

Что я хотел бы сделать

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

До сих пор

Флаг -XX:+UseLargePages прекрасно работает при использовании буфера кучи (не прямой ByteBuffers), но больше не работает при использовании DirectByteBuffers. Я также попытался использовать MappedByteBuffers и файловую систему hugetlbfs. Это работает, но поднимает ряд вопросов, поэтому я ищу другое решение.

Конфиг CentOS выпуск 6.3, точка доступа, jdk1.7

[РЕДАКТИРОВАТЬ]

Глядя на исходный код горячей точки, они используют malloc для выделения памяти с помощью Unsafe, где shmat / shmget или mmap понадобятся для использования огромных страниц.

[EDIT] Почему не куча памяти

Мы находимся в контексте NUMA для базы данных в памяти с большим количеством долгоживущих объектов. JVM не разбивает старый ген, если установлен флаг UseNUMA. Использование прямой памяти позволяет нам оставаться в памяти рядом с потоками, которые в ней нуждаются.

Очевидно, что бенчмаркинг сыграл огромную роль в решении использовать DirectByteBuffers. Я не спрашиваю, должен ли я использовать DirectByteBuffer или нет, я скорее ищу ответ на мой вопрос.

3 ответа

Решение

Для тех, кто заинтересован, ссылка на отчет об ошибке оракула

Ссылка на соответствующий билет openJDK. Закрыто, так как пока не исправлю. В Linux функция THP может помочь, хотя и имеет свои проблемы.

У вас есть тест, который однозначно показывает, что перемещение GC является узким местом для вашего приложения?

Если нет, НЕ ДЕЛАЙТЕ ЭТОГО.

Если это так, пожалуйста, добавьте ссылку на него, чтобы он мог быть рецензирован.

Такие виды низкоуровневых эффектов, как известно, трудно выделить как причину проблем с производительностью, и очень возможно потратить много времени на погоню за фантомными эффектами и выработать решение, которое пытается обойти JVM и приводит только к гораздо худшей производительности. чем было бы получено, если бы вы застряли на проторенном пути.

Обходной путь - использовать JNI для выделения памяти в C, используя любой метод, который вы хотите, и возвращать ByteBuffer. Смотрите NewDirectByteBuffer. Этот подход имеет дополнительное преимущество, заключающееся в том, что вы также можете детерминистически освободить память.

Другие вопросы по тегам