Java可运行内存不足
除了坏习惯 我们实现了一个Java线程Java可运行内存不足,java,garbage-collection,runnable,Java,Garbage Collection,Runnable,除了坏习惯 我们实现了一个Java线程Runnable,在它的run()中有一个while(true)做一些事情。while中的第一件事是try/catch/finally说,如果捕获到任何内容,请先睡眠,然后“退出”(这将在while中继续) 如果在更高级别的线程外有一个OutOfMemory问题,那么线程是否会完全消亡?如果是这样的话,try/catch/finally不会catch,因为OOM的执行超出了该范围 线程是否会被垃圾收集(它不正常地死掉) TLDR:如果一个Runnable从内
Runnable
,在它的run()
中有一个while(true)
做一些事情。while
中的第一件事是try/catch/finally
说,如果捕获到任何内容,请先睡眠,然后“退出”(这将在while中继续)
如果在更高级别的线程外有一个OutOfMemory
问题,那么线程是否会完全消亡?如果是这样的话,try/catch/finally
不会catch
,因为OOM的执行超出了该范围
线程是否会被垃圾收集(它不正常地死掉)
TLDR:如果一个Runnable
从内存中获取OutOfMemory
,它是否死亡并停止运行,或者该异常是否在执行范围内抛出
run(){
while(true){
try {
stuff
} catch{ //blah
} finally{sleep}
}
}
作业又来了
OutOfMemoryError
是一个错误,而不是异常。您可以捕获一个错误
——毕竟,它们源自可丢弃的
,异常
——但这不是一个好主意
你的线程不会死,整个JVM会死。因为当您在while循环中捕获
OutOfMemoryError
时,实际上没有任何优雅的方法可以从OutOfMemoryError
中恢复,所以您分配的所有内容(假设它们仅在循环中被引用)到内存错误点,都将符合垃圾收集的条件。(没有错误的情况下也是如此)
如果线程因OutOfMemoryError
而死亡,则其堆栈将被销毁,并且仅从该堆栈引用的所有对象也将有资格进行垃圾收集
即使主线程由于OutOfMemoryError
而死亡,如果非守护进程线程处于活动状态,jvm也不会死亡
OutOfMemoryError
可能有不同的原因,它们列在这里
通常,当您捕获到
OutOfMemoryError
时,建议进行清理并退出 当一个错误
而不是异常
发生时,整个JVM->在大多数情况下所有线程都将死亡。如果您的后台线程不使用共享的resurces,它可能会存活,但正如所说的,这是非常罕见的。 啊,如果是临终前的threas,它会死得很快
试一试决赛是什么意思? 你无法真正捕捉到错误,它就像一颗子弹: 一个错误是可以捕捉的,你可以尝试捕捉,但如果它被抛出,你就死定了
分配失败时会抛出
OutOfMemoryError
。因此,它被传递到进行分配尝试的线程的调用链。仅try…catch
块封装此调用链,resp。分配本身可能会抓住它
对JVM的整体操作和其他线程都没有直接影响。当然,如果抛出OutOfMemoryError
的原因是JVM内存不足,那么这种异常情况本身就有可能同时影响整个JVM操作或其他线程。例如,此时尝试分配的所有线程可能会失败并出现错误
如所示,如果内存太低,无法构造单个错误实例,则多个线程可能会遇到相同的OutOfMemoryError
实例。但这并不意味着抛出的错误可能会转移到不同的线程。线程中的分配失败与该线程中捕获的错误之间仍然存在因果关系。或者,如果异步操作失败,concurrency框架可能会将错误实例移交给启动线程
JVM在发生OutOfMemoryError
时自动退出的唯一原因是间接原因;如果所有非守护进程线程都是响应OutOfMemoryError
而退出的,例如当根本没有捕获它时,JVM将退出,因为这是没有非守护进程线程处于活动状态时的标准行为
在某些情况下,当JVM内存一般不低时,应用程序可以从单个失败的分配中恢复,例如,如果失败的分配非常大(表达式
new long[Integer.MAX\u VALUE-8]
需要~16GiB),如果它达到一般限制(new long[Integer.MAX\u VALUE]
不受HotSpot支持,即使有足够的内存),或者需要特殊内存而不是普通堆空间(旧JVM中的本机缓冲区、图形内存或PermGen空间)。JVM没有必要死在OutOfMemoryError
。没有作业时间。。。调试生产时间。。。不寒而栗,于是“把坏习惯放在一边”。更多的是出于我的好奇心。它也不是生产代码。你所写的是永远不会编译的伪Java。因为我将在制作一个示例时混淆prod代码,并使其简单到只包含与问题相关的信息。作为一个有趣的反驳点,Akka故意捕捉丢弃的东西,包括内存不足,以实现优雅的关闭。在大多数情况下,这是可能的。您是指在try
块中抛出的OutOfMemory
,还是从其他线程抛出的?@tsolakp看起来像是在休眠线程中抛出的WARN org.hibernate.engine.loading.internal.CollectionLoadContext:389-HH000160:On CollectionLoadContext#cleanup,localLoadingCollectionKeys包含[10]项线程“http-bio-8080-exec-25”java.lang.OutOfMemoryError:超出GC开销限制
。不久之后,我意识到,没有启动。