【问题标题】:Recovering from Out of Memory Exception within the JVM and reset JVM if possible从 JVM 中的内存不足异常中恢复并在可能的情况下重置 JVM
【发布时间】:2019-03-26 15:02:52
【问题描述】:

我正在创建一个测试套件来为我的团队正在开发的应用程序运行功能测试。功能测试是由个人开发人员编写的,我观察到一些测试用例由于各种原因抛出了 OutOfMemoryError。这会间歇性地发生。

为了处理这种情况,我想在我的测试套件中捕获 OutOfMemoryError。我希望捕捉到这个错误可以让我运行后续的测试用例,而不必一起退出应用程序。但是我看到一个帖子说垃圾收集完成后抛出内存不足错误。在这种情况下,我可以在 OutOfMemoryError 的 catch 块中做些什么来清理/重新启动 JVM,然后继续执行吗?


    Map<String, String> testcaseStatuses = new HashMap<String, String>();
    String testcaseStatus = "FAIL";
    for(Testcase testcase : testcases)
    {
        try
        {
            runTestcase(testcase);
            testcaseStatus = "SUCCESS";
        }
        catch(OutOfMemoryError e)
        {
            logError(e);
            testcaseStatus = "SYSTEM_ERROR";
                        // Do something creative to re-initialize JVM
        }
        catch (Exception e)
        {
            logError("Testcase failed with exception : " + e);
        }
        finally
        {
            testcaseStatuses.put(testcase.getName(), testcaseStatus);
        }
    }

    // Do something with testcaseStatuses   

如果第一个测试用例失败,我不想停止运行剩余的测试用例。这可行吗?

注意:我确实在 SO 上遇到过几篇关于使用

的帖子
-XX:OnOutOfMemoryError="New script to run"

这是我目前正在考虑的事情。但是为了走这条路,我必须重新设计我执行测试用例的整个方式,如果可以的话。

提前致谢。

【问题讨论】:

  • 请。请。请。上面加糖。做正确的事,并修复 OutOfMemory 错误的原因。你正试图在这里驯服混乱。
  • 我不对测试用例负责。我只负责运行测试用例。我担心的是,如果五个开发人员提出五个测试用例,而第一个测试用例因内存不足错误而失败,我不希望其他 4 个等到第一个测试用例修复后,看看他们的测试用例是否会通过。
  • 我很好奇这个问题的答案。在一个完美的世界里,@Gimby 会有完整的答案。但通常,你会得到你在我们行业中得到的东西。也许您无法控制所有涉及的代码。也许你没有时间找到所有的内存问题。也许您认为这会再次发生,并且下次也不想破坏您的测试运行。我认为你的问题是有道理的。我希望有人可以提供解决方案。我所能做的就是存储测试失败的点,然后重新开始测试并跳到该点并继续。
  • ...尝试保存内存不足的 JVM 对我来说似乎是有问题的。

标签: java out-of-memory


【解决方案1】:

不可能从 JVM 内部耗尽内存。

当然,理论上你应该修复那些 OutOfMemoryErrors 的原因,或者确保那些负责修复它们的人。但是,鉴于您所处的现实生活场景,我建议重新设计您的测试应用程序以将每个测试封装在自己的 JVM 中,例如像这样:

  • 创建一个可以执行测试的应用程序,但一次只能执行一个,由运行时参数选择。

  • 创建一个应用程序,在单独的进程中运行前一个应用程序,每个测试一次。然后使用控制台输出、日志记录数据和/或进程返回值来确定测试的状态,包括是否内存不足。

【讨论】:

  • 我已经在更高级别实施了您的第二部分解决方案。我的实际项目有点复杂。首先,我有 10 个不同的流程,每个流程都有不同数量的测试用例,从 1 到 50 不等。未来也有可能会有其他流程。还有其他要求,例如环境初始化、数据库连接等,这些要求将在 JVM 之外执行,并且开销巨大且耗时。因此需要尽可能恢复 jvm。
  • @SreeSake 不可能,尤其是在所有开销、共享数据库连接、环境等情况下。您无法从内存不足的 JVM 中可靠且安全地恢复,如果您尝试,所有地狱都可能会失败.即使可以,在“恢复”之后,您也必须丢弃并重新初始化导致错误的测试所触及的任何内容,以确保它仍然可以正常工作,因为它现在可能处于损坏状态。所以在这方面你甚至不会赢得任何东西。只是不要走那条路。越早重新设计测试套件以适应这一事实越好。
猜你喜欢
  • 2011-03-04
  • 1970-01-01
  • 2011-11-16
  • 1970-01-01
  • 1970-01-01
  • 2011-10-10
  • 2018-02-27
  • 2020-12-09
  • 2019-11-01
相关资源
最近更新 更多