Исключение нехватки памяти при компиляции файлов

 Compilefile.this.compileThread = new Thread() {
    @Override
    public void run() {
        try {
            synchronized (this) {
                Application.getDBHandler().setAutoCommit(false);
                MIBParserUtils.getDefaultMibsMap();
                compileSelectedFiles();
                Application.getDBHandler().CommitTrans();
                Application.getDBHandler().setAutoCommit(true);
            }
        }
        catch(OutOfMemoryError exp) {
            JOptionPane.showMessageDialog(null, "Compilation Stopped.. Insufficient Memory!!!");
            CompileMib.this.compileThread.interrupt();
            System.gc();

            dispose();
            NmsLogger.writeDebugLog(exp);   
        }
        finally {
        }
    }

Я попытался скомпилировать некоторые файлы в потоке. Пользовательский интерфейс выбирает более 200 файлов для компиляции. Во время компиляции произошло OutOfMemoryError из-за нехватки памяти в Eclipse. Я хочу остановить поток и отобразить окно сообщения и разместить окно компиляции в своем приложении. Я написал приведенный ниже код, но он не работает. Могу ли я поймать исключение и обработать его, или есть лучшее решение?


person Nikhil    schedule 26.09.2012    source источник
comment
Когда вы достигаете состояния OOM, состояние приложения не гарантируется. Все ставки сделаны.   -  person Frank Pavageau    schedule 26.09.2012
comment
Не можете ли вы установить больше памяти для eclipse jvm в eclipse.ini?   -  person kamuflage661    schedule 26.09.2012
comment
Могу ли я обработать исключение в блоке catch?   -  person Nikhil    schedule 26.09.2012
comment
Вы можете справиться с OOME, если есть свободная память. Попробуйте добавить byte[] bytes = new byte[64*1024]; внутрь блока try/catch.   -  person Peter Lawrey    schedule 26.09.2012
comment
Этот код нарушает стандарты кодирования Sun Java. В результате труднее читать. Почему вы храните исходный код в базе данных и компилируете его во время выполнения? Что спасает этот дизайн? Почему бы просто не скомпилировать все один раз и позволить загрузчику классов добавлять .class по мере необходимости? Псих.   -  person duffymo    schedule 26.09.2012


Ответы (3)


Могу ли я обработать исключение в блоке catch?

Вы, безусловно, можете поймать OOME. Но успешное восстановление — это совсем другое. В этом ответе обсуждаются некоторые проблемы: https://stackoverflow.com/a/1692421/139985.

Еще одна вещь, которую следует учитывать, это то, что OOME может быть запущен в другом потоке:

  • Метод compileSelectedFiles() или один из других методов может выполнять работу в другом потоке и вызывать там OOME.

  • OOME может быть вызван одним из фоновых потоков Eclipse.

В любом случае, этот catch явно не поймает.

Стоит отметить, что вызов System.gc() после OOME — пустая трата времени. Я могу гарантировать, что он не освободит память, которая все равно не будет освобождена. Все, что вы делаете, это предполагаете, что JVM тратит время на то, что не поможет. Если вам повезет, JVM проигнорирует предложение.


Я бы посоветовал просто увеличить размер кучи Eclipse, изменив параметр -Xmx JVM в файле eclipse.ini.

person Stephen C    schedule 26.09.2012
comment
Тот же основной совет из моего ответа, но с большим количеством дополнительной полезной информации :) - person Ren; 26.09.2012

Почти всегда нет надежного способа восстановиться из OOM, так как все, что вы пытаетесь поместить в блок catch, может потребовать больше памяти, которая недоступна. И GC уже сделал все возможное, прежде чем OOM был брошен, поэтому нет смысла спрашивать его снова.

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

Еще один возможный источник ошибки — утечка памяти. В этом случае есть только 1 вариант действий: найти и исправить. Plumbr может помочь в этом.

person Nikem    schedule 01.10.2012

Вы пытались добавить следующее в свой eclipse.ini (находится в той же папке, что и eclipse.exe):

-Xmx1024m

Это увеличивает пространство кучи, доступное для Eclipse. Если ваша проблема возникает во время компиляции, это может решить ее. Он дает 1 ГБ памяти в качестве ограничения пространства кучи. Попробуйте -Xmx512m, если вы не хотите выделять так много места.

person Ren    schedule 26.09.2012