изключение за липса на памет при компилиране на файлове

 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

Това, което всъщност получавате, е прокси, което всеки път ще търси правилния ресурс.
person Nikem    schedule 01.10.2012

Опитвали ли сте да добавите следното към вашия eclipse.ini (намиращ се в същата папка като eclipse.exe):

-Xmx1024m

Това увеличава пространството на купчината, достъпно за Eclipse. Ако проблемът ви е по време на компилация, това може да го реши. Той дава 1 GB памет като ограничение на пространството в купчината. Опитайте -Xmx512m, ако все пак не искате да заделяте толкова много място.

person Ren    schedule 26.09.2012