简体   繁体   English

Spring REST Service在OutOfMemoryError后不会关闭

[英]Spring REST Service does not shutdown after an OutOfMemoryError

I am experiencing what I consider a strange behaviour for a Java application. 我遇到了我认为对Java应用程序很奇怪的行为。 I am using Spring Boot 1.4.1 to develop a REST Service. 我正在使用Spring Boot 1.4.1开发REST服务。 Due to a bug in my code, an invocation to the service results in an OutOfMemoryError . 由于我的代码中的OutOfMemoryError ,对该服务的调用导致OutOfMemoryError

Surprisingly, the service responds to the request that generates the error with the following message: 令人惊讶的是,该服务使用以下消息响应生成错误的请求:

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

So far so good. 到现在为止还挺好。 What is more surprisingly is that the REST service does not shutdown after experiencing the Error . 更令人惊讶的是,遇到Error后,REST服务不会关闭。 Someone said that after an Error the best thing to do is to properly log it and shutdown everything. 有人说,发生Error ,最好的办法是正确记录该错误并关闭所有内容。 The presence of an error should mean that the system is in an unrecoverable state. 错误的出现应表示系统处于不可恢复的状态。

Why does Spring MVC adopt such a strange policy in case of Error ? 为什么在出现Error情况下Spring MVC会采用这种奇怪的策略? Is it possible to force the exit from the application (the REST service) after an Error happened? 发生Error后是否可以强制退出应用程序(REST服务)?

If you want to reproduce the above use case, just use the following code. 如果要重现上述用例,只需使用以下代码。

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

Thanks to all. 谢谢大家。

EDIT : if you do think that catching an Error is a normal way to develop Java applications, please, try to have a look to these references: 编辑 :如果您确实认为捕获Error是开发Java应用程序的正常方法,请尝试查看以下参考:

When running your application, you can specify the behavior of your application when an error like this happens with the following arguments: 运行应用程序时,可以使用以下参数指定发生此类错误时应用程序的行为:

  • -XX:+HeapDumpOnOutOfMemoryError : this will create a dump which can be analysed afterwards. -XX:+HeapDumpOnOutOfMemoryError :这将创建一个转储,以后可以对其进行分析。 The dump will be located at the location given at -XX:HeapDumpPath=some_path . 转储将位于-XX:HeapDumpPath=some_path给出的位置。
  • -XX:OnOutOfMemoryError=path_to_some_script.sh : this will run a script (it must be runnable by the same user which runs the application) when the application returns an error as an OutOfMemory -XX:OnOutOfMemoryError=path_to_some_script.sh :当应用程序将错误作为OutOfMemory返回时,它将运行一个脚本(该脚本必须由运行该应用程序的同一用户运行)。
  • -XX:OnError=path_to_some_script.sh : same as before, but for more generic exceptions. -XX:OnError=path_to_some_script.sh :与以前相同,但更多通用例外。

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

I would say that in the world of web apps this is not suprising at all. 我要说的是,在Web应用程序世界中,这一点都不令人惊讶。

Imagine a RestController as a web page. 想象一个RestController作为一个网页。 If it contains an error, the web server nor the application that generates the page is expected to stop working. 如果包含错误,则Web服务器或生成页面的应用程序都将停止工作。 This error is usually a local or temporary problem related to your request. 此错误通常是与您的请求相关的本地或临时问题。 In these situations the web server should instead respond with HTTP status 500. 在这些情况下,Web服务器应改为以HTTP状态500响应。

Spring even has an built-in error handling feature that lets you to handle each specific error differently. Spring甚至具有内置的错误处理功能,可让您以不同的方式处理每个特定的错误。 See this article by Paul Chapman for more info. 有关更多信息,请参阅Paul Chapman的这篇文章

UPDATE: Regarding your inquiry about the OOM error handling: I think you missed how memory management and object allocation in JVM works. 更新:关于您对OOM错误处理的询问:我认为您错过了JVM中的内存管理和对象分配的工作方式。 See Understand the OutOfMemoryError Exception . 请参阅了解OutOfMemoryError异常

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM