Может ли JVM представить в приложении фрагментированную память как непрерывную? [дубликат]JAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Может ли JVM представить в приложении фрагментированную память как непрерывную? [дубликат]

Сообщение Anonymous »

Современные операционные системы имеют усовершенствованные модели виртуальной памяти и хорошо представляют отдельные страницы физической памяти в виде непрерывных адресов в виртуальной памяти, во многом из-за относительно большого размера виртуального пространства в 64-битных архитектурах. Java, однако, сама по себе является крошечной операционной системой (в конце концов, виртуальной машиной) и должна реализовывать множество функций, обычно предоставляемых системами памяти.
В частности, меня несколько беспокоит использование структур на основе массивов (таких как ArrayList), особенно внутри библиотек, которые не имеют контроля или возможности оптимизировать для этого варианта использования и которые я не могу изменить самостоятельно. Например, сортировка LinkedList обычно происходит путем копирования его в массив и обратно, с чем я ничего не могу поделать, кроме поиска другой библиотеки или самостоятельной реализации некоторых функций, и мне нужно знать об этом в первую очередь. Конечно, это всего лишь простой пример распространенной проблемы.
Чтобы внести ясность: физическая память и виртуальная память ОС не имеют отношения к этому вопросу. JVM моделирует память как непрерывное адресное пространство. Чем ближе это пространство к заполнению, тем труднее выделить непрерывные фрагменты для приложения Java. Представьте, что вы запускаете JVM с параметром -Xmx16GB. Это заставит JVM использовать 32-битные указатели, ограничивая память, которую она может адресовать, до 16 ГБ (адреса увеличиваются каждые 4 байта, а не каждый байт). Допустим, процесс запрашивает массив, для которого требуется x ГБ, и в самом младшем поколении нет непрерывного фрагмента. Что будет делать JVM? Приостановить и переместить достаточно объектов, чтобы создать фрагмент подходящего размера? Мне кажется это единственный реальный вариант. Теперь замените «самое молодое поколение» общим пулом памяти, который может охватить 32-битная адресация. Перемещение такого большого объема памяти потребует значительного времени.
А что, если я использую -Xmx24GB, что заставит JVM использовать 64-битные указатели. Определяет ли ограничение памяти допустимое адресное пространство или оно применяется только к общему объему памяти, фактически запрошенному у ОС? Другими словами, ограничивает ли модель памяти адресное пространство внутри виртуальной машины размером 6*10^9? Я предполагаю, что минимальный объем выделяемой памяти здесь также составляет 4 байта, но если это 8 байт, то просто замените 6 на 3 в предыдущем предложении. Или он моделирует память как полную 2^66/2^67, сопоставленную один к одному с пространством виртуальной памяти самого процесса JVM и просто следит за тем, чтобы не запрашивать у ОС более 24 ГБ общей памяти, независимо от того, как она фрагментирована?
На мой взгляд, выделение длинного [0x7fffff00] - это случайность, ожидающая своего часа, даже если она сравнительно экстремальна для акцента. Я плохо понимаю, как JVM работает и взаимодействует с операционной системой. Однако я знаю, что очень типично ограничивать объем памяти при запуске виртуальной машины и что он должен соответствовать виртуальной памяти процесса, поскольку пользовательское пространство не имеет фактического контроля над использованием физической памяти. Выделение длинного непрерывного блока памяти должно быть особенно трудным с помощью сборщика мусора поколений, требующего глубокого запуска сборщика мусора в лучшем случае, остановки мира и перемещения вещей в крайних случаях, а также вызывающего прямую ошибку OutOfMemoryError из-за фрагментации в худшем случае.
Я что-то упускаю? Действительно ли виртуальная память вообще не проблема, или JVM может сама разделить огромный массив на куски? Или это то, что мне следует иметь в виду при написании кода, если у меня нет четкого представления о том, что реальный размер данных будет гораздо более ограниченным.
Чтобы внести ясность, я не спрашиваю об альтернативных структурах данных, в стандартной библиотеке или за ее пределами. Меня также меньше интересуют рекомендации о том, как обезопасить себя и оптимизировать собственный код. Меня беспокоят существующие библиотеки, использующие внутренние массивы или структуры на основе массивов, особенно большие, чем линейные, с пользовательскими данными без предварительной проверки размера.
Написание тестов, особенно тестов Hotspot VM, - это отдельное искусство, и я даже не представляю, как правильно определить базовый уровень такого гипотетического теста, чтобы выявить фактор непрерывности памяти, а не просто то, что выделение гигабайт за раз вообще чертовски сложно. Я даже не уверен, каким будет реалистичный сценарий. Как правило, тесты JVM, даже те хорошие, которые я видел, работают с полностью извлеченными проблемами (с целью ограничить влияние неконтролируемых переменных) и фокусируются на очень «горячем» коде C2. Это полная противоположность тому, на что я обращаю внимание, а именно на очень случайные, нехарактерно большие входные данные. Здесь меня интересуют сценарии наихудшего случая, которые не нарушат работу приложения, а не незначительное статистическое улучшение производительности.

Подробнее здесь: https://stackoverflow.com/questions/796 ... pplication
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»