2012-08-02 50 views
0

我一直认为OutOfMemoryError重新启动JVM。
但我看到其中一个OutOfMemoryError发生这不是从代码抓到一个行为(其实我甚至不知道这是可能的)
JVM继续(核心转储虽然生产)。
任何人都可以帮助我理解这种行为吗?Java中的OutOfMemoryError行为

回答

2

OutOfMemoryError向一个线程报告其内存分配失败。

int count = 0; 
long start = System.currentTimeMillis(); 
for (int i = 0; i < 10000000; i++) { 
    try { 
     long[] longs = new long[Integer.MAX_VALUE]; 
    } catch (OutOfMemoryError e) { 
     count++; 
    } 
} 
long time = System.currentTimeMillis() - start; 
System.out.printf("Got %,d OutOfMemoryErrors in %.1f seconds%n", count, time/1e3); 

打印

Got 10,000,000 OutOfMemoryErrors in 3.9 seconds 
3

OutOfMemoryError是一个例外,就像任何其他。它当然不会重新启动JVM。它可能会导致它发生的线程结束,但只有在任何地方都没有捕获到时才会发生。您可能看到的不是核心转储,而仅仅是捕获的异常的堆栈跟踪以及使用e.printStackTrace()明确打印的堆栈跟踪。

+0

所以,当我看到occusionally一个JVM重启,这是什么意思? – Jim 2012-08-02 09:23:25

+1

这意味着一个JVM启动器实际上明确地负责重新启动。它与Java本身无关。 – 2012-08-02 09:27:02

+0

所以你说,尽管转储表示堆已经被使用,但JVM仍然不会自行终止,在这种情况之后它能做什么? – Jim 2012-08-02 09:30:21

1

OutOfMemory只是当由于缺少可用内存而无法实例化对象时引发的错误。这不会停止JVM,就像没有其他异常或错误一样。

1

否可丢弃重新启动JVM。 OutOfMemoryError与其他运行时异常或错误一样:它传播调用堆栈直到被捕获。如果不是,则线程的UncaughtExceptionHandler处理此异常,通常是终止线程并打印异常的堆栈跟踪。

+0

所以当我偶尔看到一个JVM重启时,这是什么意思? – Jim 2012-08-02 09:23:34

+0

可能您已经有一些脚本或工具检测到JVM不再运行,并且重新启动它。 JVM不会自行重启。它可能完全崩溃,但不能重新启动。 – 2012-08-02 09:27:56

+0

所以,你说即使转储表示堆被使用,JVM仍然不会自行终止,在这种情况之后它能做什么? – Jim 2012-08-02 09:31:07

1

OutOfMemoryError或任何异常都不会重新启动JVM。

I am seeing a behavior where an OutOfMemoryError occurs this is not caught from the code

---->OutOfMemoryError继承java.lang.Error。错误描述了可能很少或难以从计算机内存耗尽中恢复的环境问题。您不需要处理Error类对象,但您应该使用Throwable来处理它们。这些应该被视为 环境缺陷。

看一看Exception Hierarchy

+0

设计良好的应用程序非常需要处理任何Throwables,包括OOME's。你想看到你的服务器崩溃只是因为一个请求OOME'D或SOE'd?我也不会。 – 2012-08-02 10:23:46

+0

我也不会更新答案。 :) – 2012-08-02 10:32:07