Максимальный объем памяти на процесс Java в Windows?

Каков максимальный размер кучи, который вы можете выделить для 32-разрядной Windows для процесса Java, используя -Xmx?

Я прошу, потому что я хочу использовать данные ETOPO1 в OpenMap, а исходный двоичный файл с плавающей запятой - около 910 Мб.

Ответ 1

Нет ничего лучше эмпирического эксперимента, чтобы ответить на ваш вопрос. Я написал программу Java и запустил ее, указав флаг XMX (также использовал XMS = XMX, чтобы заставить JVM предварительно выделить всю память). Для дополнительной защиты от JVM-оптимизации я активно выделяю X-номер 10 МБ объектов. Я запускаю ряд тестов на нескольких JVM, увеличивая значение XMX вместе с увеличением количества выделенных MB в разных 32-битных операционных системах, использующих как JVM Sun, так и IBM, здесь сводка результатов:

ОС: Windows XP SP2, JVM: Sun 1.6.0_02, максимальный размер кучи: 1470 МБ
ОС: Windows XP SP2, JVM: IBM 1.5, Макс. Размер кучи: 1810 МБ
ОС: Windows Server 2003 SE, JVM: IBM 1.5, Макс. Размер кучи: 1850 МБ
ОС: Linux 2.6, JVM: IBM 1.5, Макс. Размер кучи: 2750 МБ

Здесь подробный прогон выполняется вместе с исходным кодом класса размещения класса:

WinXP SP2, SUN JVM:

C:>java -version
java version "1.6.0_02"
Java(TM) SE Runtime Environment (build 1.6.0_02-b06)
Java HotSpot(TM) Client VM (build 1.6.0_02-b06, mixed mode)

java -Xms1470m -Xmx1470m Класс1 142 ... о создании объекта 141 созданный объект 141

C: > java -Xms1480m -Xmx1480m Class1 145 Ошибка при инициализации виртуальной машины Не удалось зарезервировать достаточно места для кучи объектов Не удалось создать виртуальную машину Java.

WinXP SP2, IBM JVM
 
C:>c:\ibm\jdk\bin\java.exe -version
java version "1.5.0"
Java(TM) 2 Runtime Environment, Standard Edition (build pwi32devifx-20070323 (if
ix 117674: SR4 + 116644 + 114941 + 116110 + 114881))
IBM J9 VM (build 2.3, J2RE 1.5.0 IBM J9 2.3 Windows XP x86-32 j9vmwi3223ifx-2007
0323 (JIT enabled)
J9VM - 20070322_12058_lHdSMR
JIT  - 20070109_1805ifx3_r8
GC   - WASIFIX_2007)
JCL  - 20070131

c:\ibm\jdk\bin\java.exe -Xms1810m -Xmx1810m Класс1 178 ... около объекта 177 созданный объект 177

C: > c:\ibm\jdk\bin\java.exe -Xms1820m -Xmx1820m Класс1 179 JVMJ9VM015W Ошибка инициализации библиотеки j9gc23 (2): не удалось создать экземпляр ап. 1820 млн. Запросов Не удалось создать виртуальную машину Java.

Win2003 SE, IBM JVM
C:>"C:\IBM\java" -Xms1850m -Xmx1850m Class1
sleeping for 5 seconds.
Done.

C: > "C:\IBM\java" -Xms1880m -Xmx1880m  Class1 JVMJ9VM015W Ошибка инициализации библиотеки j9gc23 (2): не удалось создать экземпляр ап. 1880M запрошено Не удалось создать виртуальную машину Java.

Linux 2.6, IBM JVM
[[email protected] ~]# /opt/ibm/java2-i386-50/bin/java -version
java version "1.5.0"
Java(TM) 2 Runtime Environment, Standard Edition (build pxi32dev-20060511 (SR2))
IBM J9 VM (build 2.3, J2RE 1.5.0 IBM J9 2.3 Linux x86-32 j9vmxi3223-20060504 (JIT enabled)
J9VM - 20060501_06428_lHdSMR
JIT  - 20060428_1800_r8
GC   - 20060501_AA)
JCL  - 20060511a

/opt/ibm/java2-i386-50/bin/java -Xms2750m -Xmx2750m Класс1 270

[root @myMachine ~] #/opt/ibm/java2-i386-50/bin/java -Xms2800m -Xmx2800m Класс1 270 JVMJ9VM015W Ошибка инициализации библиотеки j9gc23 (2): Не удалось создать экземпляр кучи. Запрошено 2800M Не удалось создать виртуальную машину Java.

Здесь код:


import java.util.StringTokenizer;


public class Class1 {

        public Class1() {}

        private class BigObject {
                byte _myArr[];
                public BigObject() {
                        _myArr = new byte[10000000];
                }
        }
    public static void main(String[] args) {
                (new Class1()).perform(Integer.parseInt(args[0]));
        }
        public void perform(int numOfObjects) {
                System.out.println("creating 10 MB arrays.");
                BigObject arr[]  = new BigObject[numOfObjects];
                for (int i=0;i <numOfObjects; i++) {
                        System.out.println("about to create object "+i);
                        arr[i] = new BigObject();
                        System.out.println("object "+i+" created");
                }
                System.out.println("sleeping for 5 seconds.");
                try {
                Thread.sleep(5000);
                }catch (Exception e) {e.printStackTrace();}
                System.out.println("Done.");
    }

}

Ответ 2

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

Ответ 3

Недавно мы портировали с Windows на Linux (из-за проблем с размерами VM).

Я слышал о большом количестве номеров, брошенных в прошлом для размера виртуальной машины Windows (1200, 1400, 1600, 1800). На наших Windows Servers (2003), в нашей среде, с нашими приложениями... Я никогда не использовал более 1280 МБ. Кроме того, наше приложение начало демонстрировать проблемы с GC и OOM.

Каждый раз, когда у меня появилась новая версия VM, я пытался изменить номер, и он никогда не менялся.

Теперь у вас есть файл 900 Мбайт, что, если файл увеличивается до 1300 МБ? Что вы будете делать?

У вас есть несколько вариантов

  • Порт для Linux/Solaris. Для этого требуется только аппаратное/программное обеспечение и то, что часто представляет собой простое упражнение по переносу.
  • Использовать 64-битную Windows. Возможно, это не исключает проблемы с GC, но я слышал о разных историях с 64-битным vms.
  • Редизайн приложения для обработки файла по-разному. Можете ли вы каким-то образом разбить файл логически, можете ли вы прочитать файл в кусках и обработать его по-другому и т.д.?

Другие люди, использующие OpenMap, должны были столкнуться с этой проблемой. Можете ли вы использовать их знания и не изобретать какие-либо колеса?

Ответ 4

Как отмечено в вопросе, упомянутом в комментарии, существует практический предел, около 1200 Мб.

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

Когда вы читаете двоичные данные из 910 MB и строите из него сетевые объекты (в отличие от просто сохранения данных в виде массива байтов), вы в конечном итоге потребляете гораздо больше памяти, чем 910 MB. Разумная оценка будет заключаться в том, что представление в памяти будет потреблять вдвое больше памяти - потому что (1) каждый объект содержит дополнительный указатель (к классу объекта); и (2) там много бухгалтерских данных. Например, если вы используете HashMap для управления вашими объектами, то в дополнение к каждому объекту вы также выделяете объект Map.Entry, который может легко потреблять 16 или 20 байтов (зависит от реализации).

С другой стороны, все еще есть надежда: вам действительно нужно поддерживать все 910 MB в памяти? Разве вы не можете просто создать что-то, что читает данные ленивым образом? В сочетании с WeakReferences я думаю, что вы можете снять это.

Ответ 5

В 32-битной Windows по умолчанию каждое приложение может использовать до 2-х виртуальных адресных пространств. Думаю, это делает -Xmx2048M. Однако, если у вас больше установленной ОЗУ, вы можете увеличить виртуальное адресное пространство до 3 GB с использованием параметров времени загрузки.

В boot.ini вы можете создать новые параметры загрузки, например:

[boot loader]<br>
timeout=5<br>
default=multi(0)disk(0)rdisk(0)partition(1)\WINDOWS<br>
[operating systems]<br>
multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Microsoft Windows XP Professional - magyar" /noexecute=optin /fastdetect /usepmtimer<br>
multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Microsoft Windows XP Professional - magyar 3GB" /noexecute=optin /fastdetect /usepmtimer /3GB /USERVA=2800<br>

Здесь, отрегулировав параметр /USERVA = 2800, вы можете настроить свой аппарат. Но имейте в виду, что некоторым конфигурациям не нравятся высокие значения в этом параметре - ожидается сбой.