在OutOfMemoryError之后,Spring REST服务不会关闭

时间:2017-02-23 16:30:40

标签: java spring spring-mvc spring-boot out-of-memory

我遇到了我认为Java应用程序的奇怪行为。我使用Spring Boot 1.4.1开发REST服务。由于我的代码中存在错误,因此对服务的调用会产生OutOfMemoryError

令人惊讶的是,该服务使用以下消息响应生成错误的请求:

{
  "timestamp": 1487862480405,
  "status": 500,
  "error": "Internal Server Error",
  "exception": "java.lang.OutOfMemoryError",
  "message": "No message available",
  "path": "/entity/exportCsv"
}

到目前为止一切顺利。更令人惊讶的是,在遇到Error之后,REST服务没有关闭。有人说,在Error之后,最好的办法是正确记录并关闭所有内容。出现错误应该意味着系统处于不可恢复的状态。

为什么Spring MVC在Error的情况下采用这种奇怪的策略? Error发生后,是否可以强制退出应用程序(REST服务)?

如果要重现上述用例,请使用以下代码。

@RestController
@RequestMapping("/entity")
class Controller {
    @RequestMapping(value = "/exportCsv", method = RequestMethod.GET)
    ResponseEntity exportCsv() {
        if (true)
            throw new OutOfMemoryError();
        return null;
    }
}

感谢所有人。

编辑:如果您认为捕获Error是开发Java应用程序的常用方法,请尝试查看这些引用:

2 个答案:

答案 0 :(得分:3)

运行应用程序时,可以使用以下参数指定应用程序的行为:

  • -XX:+HeapDumpOnOutOfMemoryError:这将创建一个可以在之后进行分析的转储。转储将位于-XX:HeapDumpPath=some_path
  • 处给出的位置
  • -XX:OnOutOfMemoryError=path_to_some_script.sh:当应用程序以OutOfMemory
  • 的形式返回错误时,这将运行一个脚本(它必须由运行应用程序的同一个用户运行)
  • -XX:OnError=path_to_some_script.sh:与之前相同,但更常见的例外情况。

参考:http://www.oracle.com/technetwork/java/javase/clopts-139448.html

答案 1 :(得分:1)

我会说,在网络应用程序的世界中,这并不令人惊讶。

想象一下RestController作为网页。如果它包含错误,则Web服务器或生成页面的应用程序预计将停止工作。此错误通常是与您的请求相关的本地或临时问题。在这些情况下,Web服务器应该以HTTP状态500响应。

Spring甚至还有一个内置的错误处理功能,可以让您以不同的方式处理每个特定的错误。有关详细信息,请参阅this article by Paul Chapman

更新:关于您对OOM错误处理的查询:我认为您错过了JVM中内存管理和对象分配的工作原理。见Understand the OutOfMemoryError Exception