Максимальный размер кучи Java для 32-разрядной JVM в 64-разрядной ОС - PullRequest
103 голосов
/ 16 сентября 2009

Вопрос не в максимальном размере кучи в 32-битной ОС, учитывая, что максимальный размер адресуемой памяти в 32-битных ОС составляет 4 ГБ, а максимальный размер кучи JVM зависит от того, сколько может быть свободной свободной памяти. зарезервирован.

Меня больше интересует знание максимального (теоретического и практически достижимого) размера кучи для 32-разрядной JVM, работающей в 64-разрядной ОС. В основном, я смотрю ответы, похожие на цифры в связанном вопросе на SO .

Что касается того, почему вместо 64-битной используется 32-битная JVM, причина не в технической, а в административной / бюрократической - вероятно, уже слишком поздно устанавливать 64-битную JVM в производственную среду.

Ответы [ 16 ]

85 голосов
/ 11 августа 2011

Вы можете задать Java Runtime:

public class MaxMemory {
    public static void main(String[] args) {
        Runtime rt = Runtime.getRuntime();
        long totalMem = rt.totalMemory();
        long maxMem = rt.maxMemory();
        long freeMem = rt.freeMemory();
        double megs = 1048576.0;

        System.out.println ("Total Memory: " + totalMem + " (" + (totalMem/megs) + " MiB)");
        System.out.println ("Max Memory:   " + maxMem + " (" + (maxMem/megs) + " MiB)");
        System.out.println ("Free Memory:  " + freeMem + " (" + (freeMem/megs) + " MiB)");
    }
}

Это сообщит о «Максимальной памяти» на основе распределения кучи по умолчанию. Так что вам все равно придется играть с -Xmx (на HotSpot ). Я обнаружил, что при работе в 64-разрядной версии Windows 7 Enterprise моя 32-разрядная HotSpot JVM может выделять до 1577 МБ:

[C:scratch]> java -Xmx1600M MaxMemory
Error occurred during initialization of VM
Could not reserve enough space for object heap
Could not create the Java virtual machine.
[C:scratch]> java -Xmx1590M MaxMemory
Total Memory: 2031616 (1.9375 MiB)
Max Memory:   1654456320 (1577.8125 MiB)
Free Memory:  1840872 (1.75559234619 MiB)
[C:scratch]>

Принимая во внимание, что 64-разрядная JVM в той же ОС, конечно, намного выше (около 3 ТБ)

[C:scratch]> java -Xmx3560G MaxMemory
Error occurred during initialization of VM
Could not reserve enough space for object heap
[C:scratch]> java -Xmx3550G MaxMemory
Total Memory: 94240768 (89.875 MiB)
Max Memory:   3388252028928 (3184151.84297 MiB)
Free Memory:  93747752 (89.4048233032 MiB)
[C:scratch]>

Как уже упоминали другие, это зависит от ОС.

  • Для 32-битной Windows: <2 ГБ (<a href="http://technet.microsoft.com/en-us/sysinternals/bb963901" rel="noreferrer"> Внутренняя книга Windows 2 ГБ для пользовательских процессов)
  • Для 32-битных BSD / Linux: <3 ГБ (из Книги Дьявола) </li>
  • Для 32-разрядной версии MacOS X: <4 ГБ (из <a href="http://osxbook.com/" rel="noreferrer"> внутренняя часть Mac OS X книга)
  • Не уверен насчет 32-битного Solaris, попробуйте приведенный выше код и сообщите нам.

Для 64-битной операционной системы, если JVM является 32-битной, она все равно будет зависеть, скорее всего, как описано выше.

- ОБНОВЛЕНИЕ 20110905 : Я просто хотел указать на некоторые другие наблюдения / детали:

  • Аппаратное обеспечение, на котором я работал, было 64-битным с установленной 6 ГБ ОЗУ. Операционная система была Windows 7 Enterprise, 64-разрядная
  • Фактическое количество Runtime.MaxMemory, которое может быть выделено, также зависит от рабочего набора операционной системы . Однажды я запустил эту программу, когда у меня также был запущен VirtualBox, и обнаружил, что не может успешно запустить JSM HotSpot с -Xmx1590M, и мне пришлось уменьшить его. Это также означает, что вы можете получить более 1590 МБ в зависимости от размера вашего рабочего набора в то время (хотя я все еще утверждаю, что он будет ниже 2 ГБ для 32-разрядных из-за дизайна Windows)
65 голосов
/ 16 сентября 2009

32-разрядные JVM, которые ожидают иметь один большой кусок памяти и используют необработанные указатели, не могут использовать более 4 ГБ (поскольку это 32-разрядное ограничение, которое также применяется к указателям). Это включает в себя Sun и, я уверен, также реализации IBM. Я не знаю, например, JRockit или другие имеют большой объем памяти в своих 32-битных реализациях.

Если вы ожидаете, что достигнете этого предела, вам настоятельно рекомендуется запустить параллельный трек для проверки 64-битной JVM для вашей производственной среды, чтобы вы были готовы к тому, что 32-битная среда выйдет из строя. В противном случае вам придется выполнять эту работу под давлением, что никогда не бывает приятно.


Редактировать 2014-05-15: FAQ по Oracle:

Максимальный теоретический предел кучи для 32-разрядной JVM составляет 4G. Из-за различных дополнительных ограничений, таких как доступный обмен, использование адресного пространства ядра, фрагментация памяти и издержки на виртуальные машины, на практике этот предел может быть намного ниже. В большинстве современных 32-разрядных систем Windows максимальный размер кучи будет варьироваться от 1,4 ГГ до 1,6 ГБ. В 32-битных ядрах Solaris адресное пространство ограничено 2G. В 64-разрядных операционных системах, работающих под управлением 32-разрядной виртуальной машины, максимальный размер кучи может быть выше, приближаясь к 4G во многих системах Solaris.

(http://www.oracle.com/technetwork/java/hotspotfaq-138619.html#gc_heap_32bit)

16 голосов
/ 16 сентября 2009

Вы не указываете , который ОС.

Под Windows (для моего приложения - долго работающего приложения для управления рисками) мы заметили, что на Windows 32bit мы не можем идти дальше 1280 МБ. Я сомневаюсь, что использование 32-битной JVM под 64-битной системой имело бы какое-либо значение.

Мы портировали приложение на Linux, и мы запускаем 32-битную JVM на 64-битном оборудовании, а виртуальная машина на 2,2 ГБ работала довольно легко.

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

14 голосов
/ 02 декабря 2009

С 4.1.2 Размер кучи :

"Для 32-разрядной модели процесса максимальный размер виртуального адреса процесс обычно составляет 4 ГБ, хотя некоторые операционные системы ограничивают это 2 ГБ или 3 ГБ. Максимальный размер кучи обычно составляет -Xmx3800m (1600m) для 2 ГБ), хотя фактическое ограничение зависит от приложения. Для 64-битных моделей процессов максимум практически не ограничен. "

Нашел довольно хороший ответ здесь: Максимальная память Java в Windows XP .

12 голосов
/ 04 июля 2011

У нас недавно был некоторый опыт с этим. Недавно мы перенесли с Solaris (x86-64 версии 5.10) на Linux (RedHat x86-64) и поняли, что у нас меньше памяти для 32-битного процесса JVM в Linux, чем Solaris.

Для Solaris это почти до 4 ГБ (http://www.oracle.com/technetwork/java/hotspotfaq-138619.html#gc_heap_32bit).

Мы запустили наше приложение с -Xms2560m -Xmx2560m -XX: MaxPermSize = 512m -XX: PermSize = 512m без проблем в Solaris в течение последних нескольких лет. Попытка переместить его в Linux, и у нас были проблемы со случайными ошибками нехватки памяти при запуске. Мы могли только заставить его последовательно запускаться на -Xms2300 -Xmx2300 . Тогда нам сообщили об этом из поддержки.

32-битный процесс в Linux имеет максимальное адресуемое адресное пространство 3gb (3072mb), тогда как на Solaris это полный 4 ГБ (4096 МБ).

9 голосов
/ 16 сентября 2009

Ограничения 32-разрядной JVM в 64-разрядной ОС будут точно такими же, как ограничения 32-разрядной JVM в 32-разрядной ОС. В конце концов, 32-разрядная JVM будет работать на 32-разрядной виртуальной машине (в смысле виртуализации), поэтому она не будет знать, что она работает на 64-разрядной ОС / машине.

Одним из преимуществ использования 32-разрядной JVM в 64-разрядной ОС по сравнению с 32-разрядной ОС является то, что у вас может быть больше физической памяти, и, следовательно, вы будете сталкиваться с подкачкой / подкачкой реже. Однако это преимущество полностью реализуется только при наличии нескольких процессов.

6 голосов
/ 15 марта 2013

Относительно того, почему вместо 64-битной используется 32-битная JVM, причина не техническая, а административная / бюрократическая ...

Когда я работал на BEA, мы обнаружили, что среднее приложение на самом деле работает медленнее в 64-битной JVM, а затем при работе в 32-битной JVM. В некоторых случаях снижение производительности было на 25% медленнее. Поэтому, если вашему приложению действительно не нужна вся эта дополнительная память, вам лучше настроить больше 32-разрядных серверов.

Насколько я помню, тремя наиболее распространенными техническими обоснованиями для использования 64-разрядных систем, с которыми столкнулись сотрудники служб BEA, были:

  1. Приложение манипулирует несколькими массивными изображениями,
  2. Приложение выполняло массовые вычисления,
  3. Приложение имело утечку памяти, клиент был основным на государственный контракт, и они не хотели тратить время и за счет отслеживания утечки памяти. (Используя массивную память куча увеличит MTBF, а простое число все равно будет выплачено)

.

4 голосов
/ 03 мая 2013

Вот некоторые тесты под Solaris и Linux 64-bit

Solaris 10 - SPARC - аппарат T5220 с 32 ГБ ОЗУ (и около 9 ГБ свободно)

$ java -XX:PermSize=128M -XX:MaxPermSize=256M -Xms512m -Xmx3750m MaxMemory
Error occurred during initialization of VM
Could not reserve space for ObjectStartArray
$ java -XX:PermSize=128M -XX:MaxPermSize=256M -Xms512m -Xmx3700m MaxMemory
Total Memory: 518520832 (494.5 MiB)
Max Memory:   3451912192 (3292.0 MiB)
Free Memory:  515815488 (491.91998291015625 MiB)
Current PID is: 28274
Waiting for user to press Enter to finish ...

$ java -version
java version "1.6.0_30"
Java(TM) SE Runtime Environment (build 1.6.0_30-b12)
Java HotSpot(TM) Server VM (build 20.5-b03, mixed mode)

$ which java
/usr/bin/java
$ file /usr/bin/java
/usr/bin/java: ELF 32-bit MSB executable SPARC Version 1, dynamically linked, not stripped, no debugging information available

$ prstat -p 28274
   PID USERNAME  SIZE   RSS STATE  PRI NICE      TIME  CPU PROCESS/NLWP
28274 user1     670M   32M sleep   59    0   0:00:00 0.0% java/35

Кстати: очевидно, Java не выделяет много фактической памяти при запуске. Похоже, что на каждый запущенный экземпляр уходит только около 100 МБ (я начал 10)

Solaris 10 - x86 - VMWare VM с 8 ГБ ОЗУ (около 3 ГБ свободно *)

3 ГБ свободной оперативной памяти на самом деле не соответствуют действительности. Существует большой кусок оперативной памяти, который используют кеши ZFS, но у меня нет доступа с правами root, чтобы проверить, сколько именно

$ java -XX:PermSize=128M -XX:MaxPermSize=256M -Xms512m -Xmx3650m MaxMemory
Error occurred during initialization of VM
Could not reserve enough space for object heap
Could not create the Java virtual machine.

$ java -XX:PermSize=128M -XX:MaxPermSize=256M -Xms512m -Xmx3600m MaxMemory
Total Memory: 516423680 (492.5 MiB)
Max Memory:   3355443200 (3200.0 MiB)
Free Memory:  513718336 (489.91998291015625 MiB)
Current PID is: 26841
Waiting for user to press Enter to finish ...

$ java -version
java version "1.6.0_41"
Java(TM) SE Runtime Environment (build 1.6.0_41-b02)
Java HotSpot(TM) Server VM (build 20.14-b01, mixed mode)

$ which java
/usr/bin/java

$ file /usr/bin/java
/usr/bin/java:  ELF 32-bit LSB executable 80386 Version 1 [FPU], dynamically linked, not stripped, no debugging information available

$ prstat -p 26841
   PID USERNAME  SIZE   RSS STATE  PRI NICE      TIME  CPU PROCESS/NLWP
26841 user1     665M   22M sleep   59    0   0:00:00 0.0% java/12

RedHat 5.5 - x86 - VMWare VM с 4 ГБ ОЗУ (используется около 3,8 ГБ - 200 МБ в буферах и 3,1 ГБ в кэшах, поэтому около 3 ГБ свободно)

$ alias java='$HOME/jre/jre1.6.0_34/bin/java'

$ java -XX:PermSize=128M -XX:MaxPermSize=256M -Xms512m -Xmx3500m MaxMemory
Error occurred during initialization of VM
Could not reserve enough space for object heap
Could not create the Java virtual machine.

$ java -XX:PermSize=128M -XX:MaxPermSize=256M -Xms512m -Xmx3450m MaxMemory
Total Memory: 514523136 (490.6875 MiB)
Max Memory:   3215654912 (3066.6875 MiB)
Free Memory:  511838768 (488.1274871826172 MiB)
Current PID is: 21879
Waiting for user to press Enter to finish ...

$ java -version
java version "1.6.0_34"
Java(TM) SE Runtime Environment (build 1.6.0_34-b04)
Java HotSpot(TM) Server VM (build 20.9-b04, mixed mode)

$ file $HOME/jre/jre1.6.0_34/bin/java
/home/user1/jre/jre1.6.0_34/bin/java: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.2.5, dynamically linked (uses shared libs), for GNU/Linux 2.2.5, not stripped

$ cat /proc/21879/status | grep ^Vm
VmPeak:  3882796 kB
VmSize:  3882796 kB
VmLck:         0 kB
VmHWM:     12520 kB
VmRSS:     12520 kB
VmData:  3867424 kB
VmStk:        88 kB
VmExe:        40 kB
VmLib:     14804 kB
VmPTE:        96 kB

Та же машина, использующая JRE 7

$ alias java='$HOME/jre/jre1.7.0_21/bin/java'

$ java -XX:PermSize=128M -XX:MaxPermSize=256M -Xms512m -Xmx3500m MaxMemory
Error occurred during initialization of VM
Could not reserve enough space for object heap
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.

$ java -XX:PermSize=128M -XX:MaxPermSize=256M -Xms512m -Xmx3450m MaxMemory
Total Memory: 514523136 (490.6875 MiB)
Max Memory:   3215654912 (3066.6875 MiB)
Free Memory:  511838672 (488.1273956298828 MiB)
Current PID is: 23026
Waiting for user to press Enter to finish ...

$ java -version
java version "1.7.0_21"
Java(TM) SE Runtime Environment (build 1.7.0_21-b11)
Java HotSpot(TM) Server VM (build 23.21-b01, mixed mode)

$ file $HOME/jre/jre1.7.0_21/bin/java
/home/user1/jre/jre1.7.0_21/bin/java: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.6.9, dynamically linked (uses shared libs), for GNU/Linux 2.6.9, not stripped

$ cat /proc/23026/status | grep ^Vm
VmPeak:  4040288 kB
VmSize:  4040288 kB
VmLck:         0 kB
VmHWM:     13468 kB
VmRSS:     13468 kB
VmData:  4024800 kB
VmStk:        88 kB
VmExe:         4 kB
VmLib:     10044 kB
VmPTE:       112 kB
4 голосов
/ 11 декабря 2011

JVC JROCKIT, в настоящее время принадлежащая Oracle, поддерживает несмежное использование кучи, что позволяет 32-битной JVM получить доступ к более чем 3,8 ГБ памяти, когда JVM работает в 64-битной ОС Windows. (2,8 ГБ при работе в 32-битной ОС).

http://blogs.oracle.com/jrockit/entry/how_to_get_almost_3_gb_heap_on_windows

JVM можно бесплатно загрузить (требуется регистрация) на

http://www.oracle.com/technetwork/middleware/jrockit/downloads/index.html

3 голосов
/ 16 сентября 2009

Должно быть намного лучше

Для 32-разрядной JVM, работающей на 64-разрядном хосте, я представляю, что останется куча для того, что будет доступно после нефрагментированного виртуального пространства после JVM, его собственных библиотек DLL и любых компонентов совместимости с 32-разрядной ОС. был загружен. Как дикое предположение, я бы подумал, что 3ГБ должно быть возможным, но насколько это лучше, зависит от того, насколько хорошо вы справляетесь с 32-битным хостом.

Кроме того, даже если вы можете создать гигантскую кучу объемом 3 ГБ, вы, возможно, этого не захотите, поскольку это может привести к тому, что паузы в GC станут потенциально неприятными. Некоторые люди просто запускают больше JVM, чтобы использовать дополнительную память, а не одну гигантскую. Я полагаю, что они сейчас настраивают JVM, чтобы лучше работать с гигантскими кучами.

Немного сложно точно знать, насколько лучше ты можешь сделать. Я думаю, что ваша 32-битная ситуация может быть легко определена экспериментом. Безусловно, это трудно предсказать абстрактно, так как на это влияют многие факторы, особенно потому, что виртуальное пространство, доступное на 32-разрядных хостах, довольно ограничено. Куча должна существовать в смежной виртуальной памяти, поэтому фрагментация адресного пространства для Использование DLL и внутреннее использование адресного пространства ядром ОС определит диапазон возможных распределений.

ОС будет использовать часть адресного пространства для отображения устройств HW и своих собственных динамических распределений. Хотя эта память не отображается в адресное пространство процесса Java, ядро ​​ОС не может получить к нему доступ и к вашему адресному пространству одновременно, поэтому оно ограничит размер виртуального пространства любой программы.

Загрузка DLL зависит от реализации и выпуска JVM. Загрузка ядра ОС зависит от огромного количества вещей, релиза, HW, от того, сколько оно отображено с момента последней перезагрузки, кто знает ...

В итоге

Могу поспорить, что вы получите 1-2 ГБ в 32-битной среде и около 3 в 64-битной, поэтому общее улучшение составит примерно 2x .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...