Есть ли способ увеличить пространство кучи Java в самом коде?

Возможный дубликат:
Можно ли динамически изменять максимальный размер кучи java?

Я знаю, что есть опция XMX для средства запуска Java, но есть ли какая-то директива предварительной обработки, которая делает это вместо этого (так что на всех компьютерах, на которых выполняется мой код, будет увеличена куча).

На данный момент java.exe достигает только ~ 280 МБ (до сбоя) - это нормально?


person Wuschelbeutel Kartoffelhuhn    schedule 08.12.2012    source источник
comment
Связанный: stackoverflow.com/questions/193483/   -  person Captain Giraffe    schedule 09.12.2012
comment
Есть ли способ увеличить пространство кучи Java в самом коде? Нет - как только код загружен, доступная память уже установлена ​​(в камне). Одно из решений - проверить память в текущей виртуальной машине и, если ее недостаточно: 1) запустить новый Process с большим объемом памяти 2) выйти.   -  person Andrew Thompson    schedule 09.12.2012
comment
@Andrew Thompson: запустите новый процесс с большим объемом памяти, можно ли это сделать в коде?   -  person Wuschelbeutel Kartoffelhuhn    schedule 09.12.2012


Ответы (3)


"запустить новый процесс с большим объемом памяти" можно ли это сделать в коде?

да. См. Этот упрощенный пример.

import java.awt.EventQueue;
import javax.swing.JOptionPane;
import java.io.File;

class BigMemory {

    public static void main(String[] args) throws Exception {
        if (args.length==0) {
            ProcessBuilder pb = new ProcessBuilder(
                "java",
                "-Xmx1024m",
                "BigMemory",
                "anArgument"
                );
            pb.directory(new File("."));
            Process process = pb.start();
            process.waitFor();
            System.out.println("Exit value: " + process.exitValue());
        } else {
            Runnable r = new Runnable() {
                public void run() {
                    JOptionPane.showMessageDialog(
                        null,
                        "Max Memory: " +
                        Runtime.getRuntime().maxMemory() +
                        " bytes.");
                }
            };
            EventQueue.invokeLater(r);
        }
    }
}
person Andrew Thompson    schedule 09.12.2012

Ответ - нет".

Размер памяти передается JVM при запуске. Код, работающий внутри JVM, не может его изменить.

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

person Bohemian♦    schedule 08.12.2012
comment
Если я хочу пойти по маршруту XMX, в какой исполняемый файл java нужно добавить это свойство запуска? ... Я только что выполнил поиск java.exe и получил около двух десятков результатов ... - person Wuschelbeutel Kartoffelhuhn; 09.12.2012
comment
или мне нужно ввести это в cmd.exe? - person Wuschelbeutel Kartoffelhuhn; 09.12.2012
comment
Это должен быть параметр командной строки. Это не то, что вы можете установить глобально. Обычно это разумное значение, которое предполагает, что либо а) у вашей машины мало памяти, либо, что более вероятно, б) проблема не в том, что вы думаете, поскольку вы не очень четко указывали, в чем заключается сбой. IMHO сбой означает, что у вас есть необработанный сигнал, и у вас будет записан файл дампа, а не ошибка или исключение. - person Peter Lawrey; 09.12.2012

Не было бы максимума, если бы можно было увеличить.

Причина, по которой его нельзя увеличить, заключается в том, что он выделяется при запуске. Его можно установить только до запуска JVM.

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

Примечание: если вы используете память вне кучи, она может быть больше ГБ или даже ТБ, так как это не является частью максимума.

На данный момент java.exe достигает только ~ 280 МБ (до сбоя) - это нормально?

Сбои могут означать что угодно, а причиной может быть что угодно. Я предлагаю вам более подробно изучить, почему он не работает, и я подозреваю, что вы обнаружите, что проблема не в максимальной памяти. (Если у вас нет небольшой машины с 1 ГБ, в этом случае максимальная память по умолчанию будет около 250 МБ)

person Peter Lawrey    schedule 09.12.2012
comment
Где я должен ввести атрибут XMX? Я не могу найти командную строку JVM. Вы, вероятно, правы, что здесь виноват не максимальный размер кучи. - person Wuschelbeutel Kartoffelhuhn; 09.12.2012
comment
Его можно установить только в командной строке. Как у вас работает программа Java? Сколько у вас основной памяти? - person Peter Lawrey; 09.12.2012
comment
16 ГБ, когда я ввожу его в cmd.exe, я получаю, что java не распознается как внутренняя или внешняя команда - person Wuschelbeutel Kartoffelhuhn; 09.12.2012
comment
Кроме того, я запускаю его в jgrasp - person Wuschelbeutel Kartoffelhuhn; 09.12.2012
comment
Если у вас 16 ГБ и у вас есть сервер jvm (любая 64-разрядная версия или unix), то максимальный объем памяти будет 1/4 или 4 ГБ. Поскольку у вашей программы проблемы задолго до того, как она достигнет этой точки, я подозреваю, что проблема не в максимальной памяти. Вам необходимо пояснить, что вы имеете в виду под крахом - person Peter Lawrey; 09.12.2012
comment
У меня может быть установлен 32-битный jvm. изменить: действительно: это в моей папке программных файлов x86. сколько в таком случае макс? - person Wuschelbeutel Kartoffelhuhn; 09.12.2012
comment
Исключение в основном потоке java.lang.OutOfMemoryError: пространство кучи Java в java.util.HashMap.createEntry (неизвестный источник) - person Wuschelbeutel Kartoffelhuhn; 09.12.2012
comment
Если вы также используете Windows, тогда он запускает 32-разрядную виртуальную машину, которая ограничивает вашу память примерно до 1,2 ГБ. Максимальный размер памяти по умолчанию для клиентской версии составляет 64 МБ, поэтому я не думаю, что вы это используете) - person Peter Lawrey; 09.12.2012
comment
Я думаю, вам нужно выяснить, что именно происходит, прежде чем приложение умрет, потому что для меня это не имеет особого смысла. Я предлагаю вам наблюдать за процессом в VisualVM, чтобы отслеживать использование памяти. - person Peter Lawrey; 09.12.2012
comment
Хорошо, я загрузил его, и он говорит, что размер кучи составляет 200 МБ, а через некоторое время он увеличивается до 268 МБ (после того, как мой HashMap растет), и после этого он больше не увеличивает кучу :( Вот снимок экрана: i.imgur.com/ICVQT.jpg - person Wuschelbeutel Kartoffelhuhn; 09.12.2012
comment
Это подтверждает то, что вы говорите. Я только предполагаю, что вы используете 32-разрядную версию сервера, для которой максимальный размер кучи по умолчанию составляет ~ 268 МБ. Вы уверены, что ваша последняя версия 64-битная? Другая возможность заключается в том, что вы запускаете свое приложение из среды, которая неправильно его настраивает, потому что по умолчанию в вашей системе должно быть 4 ГБ (для 64-разрядной версии). - person Peter Lawrey; 09.12.2012