Укажите адрес пула выделения памяти Java - PullRequest
4 голосов
/ 03 января 2011

С помощью параметров -Xms и -Xmx можно установить начальный и максимальный размер пула выделения памяти. Я обнаружил, что используя strace / truss в Linux и AIX, JVM внутренне использует системный вызов (k) mmap. address -Parameter равен NULL, поэтому операционная система решает, по какому адресу виртуальной памяти она отображает память.

$ truss java -Xmx512M Hello 2>&1 | grep mmap
kmmap(0x00000000, 536870912, 3, 17, -1, 0x00000000, 0x00000000) = 0xB0000000

Возможно, указать этот адрес?

Справочная информация. Мне приходится вызывать унаследованный код через собственный интерфейс Java (JNI), для которого требуются огромные объемы неразмещаемых данных (2 ГБ в 32-разрядном адресном пространстве), отображаемых в определенном месте памяти. Этот регион перекрывается с расположением пула выделения памяти Javas.

Редактировать: Это фактический макет памяти:

0x0... AIX
0x1... Text
0x2... Stack
0x3... Heap
0x4... Heap
...... Legacy Data (2 GB)
0xd... Shared Library Text
0xe... unused
0xf... Shared Library Data

Моя цель - переместить пул выделения памяти Java из 0xb / 0xc в сегменты 0x3 / 0x4, что также доступно в стандартной (небольшой) модели памяти.

Ответы [ 3 ]

2 голосов
/ 03 января 2011

Возможно, вы могли бы вывернуть эту проблему наизнанку.Запустите собственный процесс и сделайте то, что вам нужно, чтобы зарезервировать не подлежащее обсуждению пространство (mmap или что-то еще).Затем используйте Java invocation API для создания и запуска JVM внутри собственного процесса.Я не могу найти никакой документации о том, как эта JVM осуществляет управление памятью, но понятно, что хорошо будет играть с памятью, которая уже была выделена хост-процессом (я думаю, она просто используетлокальный malloc), поэтому он найдет где-то еще, чтобы положить свою кучу.Если вы оставите регион 0x3-0x4 нераспределенным, вы можете надеяться, что он поместит его туда.

Однако я думаю, что существует реальный риск того, что в вашей модели памяти просто не хватит адресного пространства для JVM.Область 0x3-0x4 - это что, 512 МБ?Если вы можете разместить там целую JVM (кучу, стек, перманент, структуры виртуальных машин и т. Д.), Тогда хорошо, но если нет, вы можете обнаружить, что когда JVM не может выделить непрерывную память для кучи, это очень расстраивает,Или не может.Я действительно не знаю.

Итак, предложив это, я настоятельно рекомендую вам не делать этого, а вместо этого следовать совету sleske и поместить собственный код в отдельныйпроцесс.

2 голосов
/ 03 января 2011

Лично я никогда не слышал о способе настройки адреса пула выделения. Если есть такая настройка, она, вероятно, очень неясна.

Единственный способ убедиться в этом - взглянуть на источник JDK / JRE, доступный по адресу http://hg.openjdk.java.net/. Если параметр NULL жестко запрограммирован, вам не повезло.

Для альтернативного решения, если вы не можете исправить некорректно работающий нативный код:

Вы можете написать небольшую собственную программу для вызова вашего собственного кода, а затем вызвать программу из Java (через Runtime.exec). Таким образом, непослушный код получает свой собственный процесс ОС с отдельным адресным пространством. Конечно, это возможно только в том случае, если между нативным кодом и Java не слишком много обратной связи.

Или превратить код в небольшой сервер, который работает параллельно с вашим Java-приложением, чтобы они могли взаимодействовать ...

Дополнительное примечание:

Я только что заметил на странице справки mmap, что присвоение адреса mmap не обязательно поддерживается:

MAP_FIXED: точно интерпретировать адрес. [...] Это определяется реализацией MAP_FIXED должен поддерживаться. MAP_FIXED должен поддерживаться на XSI-совместимые системы. [...] Когда MAP_FIXED не установлен, реализация использует адрес в определяемый реализацией способ прибыть в год.

http://linux.die.net/man/3/mmap

Таким образом, даже если вам удастся разрешить JVM вызвать mmap по определенному адресу, это все равно может не сработать.

1 голос
/ 03 января 2011

Одна из идей, которую вы можете попробовать, - использовать LD_PRELOAD для внедрения вашего собственного поведения kmmap. Google предоставляет пример LD_PRELOAD для внедрения пользовательского malloc в проект TCMalloc .

...