Теория # 1
Когда вы запрашиваете кучу 35 Гбайт с использованием -Xmx35000m, вы на самом деле говорите, что общий объем пространства, используемого для кучи, составляет 35 Гб.Но общее пространство состоит из пространства Tenured Object (для объектов, переживших несколько циклов GC), пространства Eden для вновь создаваемых объектов и других пространств, в которые объекты будут копироваться во время сборки мусора.
Проблема заключается в том,что некоторые пробелы не используются и не могут быть использованы для размещения новых объектов.Таким образом, по сути, вы «теряете» значительный процент своих 35 ГБ на накладные расходы.
Существуют различные опции -XX, которые можно использовать для изменения размеров соответствующих пространств и т. Д. Вы можете попробовать поиграться с нимичтобы увидеть, если они имеют значение.Обратитесь к этому документу для получения дополнительной информации.(Обычно используемые параметры настройки GC перечислены в разделе 8. Параметр -XX: NewSpace выглядит многообещающе ...)
Theory # 2
Это может происходить из-за того, что вывыделяя огромные объекты.IIRC, объекты выше определенного размера могут быть размещены непосредственно в пространстве объекта аренды.В вашем (очень искусственном) тесте это может привести к тому, что JVM не помещает вещи в пространство Eden и, следовательно, может использовать меньше всего пространства кучи, чем обычно.
В качестве эксперимента попробуйте изменить свой эталонный тест, чтобы выделить множество небольших объектов, и посмотрите, удастся ли ему использовать больше доступного пространства перед выходом.
Вот некоторые другие теории, которые я бы не учел:
«Вы работаете в рамках ограничений, установленных ОС».Я бы проигнорировал это, поскольку вы сказали, что вы можете значительно увеличить использование памяти, увеличив параметр -Xmx ...
«Диспетчер задач Windows сообщает фиктивные числа».Я бы обесценил это, потому что указанные цифры примерно соответствуют 25 ГБ, которые, по вашему мнению, удалось выделить вашему приложению.
«Вы теряете место для других вещей, например, кучи permgen».AFAIK, размер кучи permgen контролируется и учитывается независимо от «нормальных» куч.Другое использование памяти без кучи является либо постоянным (для приложения), либо зависит от выполнения определенными действиями приложения.
«Вы страдаете от фрагментации кучи».Все сборщики мусора JVM являются «копирующими сборщиками», и у этого семейства сборщиков есть свойство автоматически сжимать узлы кучи.
«Ошибка JVM в Windows».Очень маловероятно.В Windows должно быть несколько десятков тысяч 64-битных Java-приложений, которые максимизируют размер кучи.Кто-то еще заметил бы ...
Наконец, если вы НЕ делаете этого, потому что ваше приложение требует, чтобы вы выделяли память большими кусками и зависали "навсегда""... есть хороший шанс, что вы гоняетесь за тенями.«Нормальное» приложение с большой памятью такого не делает, а JVM настроена на нормальные приложения ... не аномальные.
И если ваше приложение действительно ведет себя таким образом, прагматичнорешение состоит в том, чтобы просто установить параметр -Xmx ... больше и беспокоиться, только если вы начнете сталкиваться с проблемами на уровне ОС.