不好的做法......
我们实现了一个Java线程Runnable
,并在其run()
中有while(true)
做了一些事情。 while
内的第一件事就是try/catch/finally
说,如果发现任何事情,请先睡觉,然后“退出”(这会持续一段时间)。
如果在更高级别的线程外有OutOfMemory
问题,线程是否会完全死掉?如果是这样,try/catch/finally
将不会catch
,因为OOM的执行超出了该范围?
线程是否会被垃圾收集(它不合理地死亡)。
TLDR:如果Runnable
得到OutOfMemory
它会死掉并且只是停在其轨道上,或者是在执行范围内抛出该异常?
run(){
while(true){
try {
stuff
} catch{ //blah
} finally{sleep}
}
}
答案 0 :(得分:2)
当Error
而不是Exception
发现整个JVM时 - >在大多数情况下,所有线程都会死亡。
如果你的后台线程没有使用共享的resurces,那么它可能会受到冲击,但正如所说的非常罕见。
啊,如果它是一个deamon threas它会死于instat。
try catch final是什么意思?
你不能真正发现错误,它就像一颗子弹:
错误是可以捕获的,你可以尝试捕获,但如果它被抛出你就死了。
答案 1 :(得分:2)
分配失败时抛出OutOfMemoryError
。因此,它被传递到进行分配尝试的线程的调用链。只有try … catch
块封装了这个调用链,resp。分配本身可能会抓住它。
对JVM的整体操作和其他线程没有直接影响。当然,如果抛出OutOfMemoryError
的原因是JVM内存不足,那么这种特殊情况本身可能同时影响整个JVM操作或其他线程。例如,当时尝试分配的所有线程可能会因错误而失败。
如this answer所示,如果内存太低而无法构造单个错误实例,则多个线程可能会遇到相同的OutOfMemoryError
实例。但这并不意味着抛出的错误可能会转移到不同的线程。线程中的失败分配与该线程中捕获的错误之间仍存在因果关系。或者,如果异步操作失败,并发框架可能会将错误实例移交给启动线程。
JVM在OutOfMemoryError
上自动退出的唯一原因是间接的;如果所有非守护进程线程都退出以响应OutOfMemoryError
,例如当没有捕获它时,JVM将退出,因为当没有非守护程序线程处于活动状态时,这是标准行为。
有些情况下,当JVM内存不低时,应用程序可以从单个失败的分配中恢复,例如,如果失败的分配非常大(表达式new long[Integer.MAX_VALUE-8]
需要~16GiB),如果它遇到一般限制(HotSpot不支持new long[Integer.MAX_VALUE]
,即使有足够的内存),或者需要特殊的内存而不是普通堆空间(旧JVM中的本机缓冲区,图形内存或PermGen空间)。
答案 2 :(得分:1)
再次做作业时间?
OutOfMemoryError
是错误,不是例外。您可以捕获Error
- 所有,它们来自Throwable
,Exception
也是如此 - 但这不是一个好主意。
您的线程不会死,您的整个JVM都会死。因为从OutOfMemoryError
恢复真的没有优雅的方式。
答案 3 :(得分:1)
当您在while循环中捕获OutOfMemoryError
时,您分配的所有内容(假设它们仅在您的循环中引用)直到点内存错误,将有资格进行垃圾回收。(这也是没有的情况)错误)
如果一个线程由于OutOfMemoryError
而死亡,它的堆栈将被销毁,并且仅从该堆栈引用的所有对象也将有资格进行垃圾收集。
如果你的非守护程序线程处于活动状态,即使主线程由于OutOfMemoryError
而死亡,jvm也不会死亡。
OutOfMemoryError
可能有不同的原因,这里列出https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/memleaks002.html
通常建议您在抓住OutOfMemoryError
时清理并退出。