3
 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 {
        }
    }

我试图在一个线程中编译一些文件。UI 选择了 200 多个文件进行编译。在编译期间OutOfMemoryError由于 Eclipse 中的内存不足而发生。我想停止线程并显示一个消息框并在我的应用程序中处理编译窗口。我写了下面的代码,但它不起作用。我可以捕获异常并处理它,还是有更好的解决方案?

4

3 回答 3

1

我可以处理 catch 块中的异常吗?

你当然可以赶上 OOME。但成功恢复完全是另一回事。这个答案讨论了一些问题:https ://stackoverflow.com/a/1692421/139985 。

另一件需要考虑的事情是 OOME 可能被抛出到不同的线程上:

  • compileSelectedFiles()方法或其他方法之一可能正在另一个线程上完成工作并在那里抛出 OOME。

  • OOME 可能被抛出 Eclipse 的后台线程之一。

在任何一种情况下,这catch显然都不会抓住它。

值得注意的是,System.gc()在 OOME 之后调用是浪费时间。我可以保证它不会释放任何无论如何都不会释放的内存。您所做的只是建议JVM 将时间浪费在无济于事的事情上。如果幸运的话,JVM 会忽略这个建议。


我的建议是通过更改-Xmxeclipse.ini 文件中的 JVM 参数来增加 Eclipse 的堆大小。

于 2012-09-26T10:21:29.017 回答
1

从 OOM 中恢复几乎总是没有可靠的方法,因为您尝试放入 catch 块中的任何内容都可能需要更多内存,而这是不可用的。而且GC在OOM被抛出之前已经尽力了,所以再问他也没用。

与往常一样,您可以通过 Xmx 选项增加应用程序可用的内存量,或者修复您的应用程序使其不需要那么多内存。

另一种可能的错误来源是内存泄漏。在这种情况下,只有 1 个操作过程:找到并修复它。Plumbr可以在这方面提供帮助。

于 2012-10-01T09:39:00.450 回答
0

您是否尝试将以下内容添加到 eclipse.ini(与 eclipse.exe 位于同一文件夹中):

-Xmx1024m

这增加了 Eclipse 可用的堆空间。如果您的问题是在编译期间,这可能会解决它。它提供 1GB 的内存作为堆空间限制。-Xmx512m如果您不想分配这么多空间,请尝试。

于 2012-09-26T10:07:12.260 回答