[英]Java Runnable Out of Memory
Bad practices aside... 除了不良做法...
We implement a Java Thread Runnable
and in its run()
have a while(true)
do some stuff. 我们实现了Java线程
Runnable
并在它的run()
有一阵while(true)
做一些事情。 First thing inside the while
is a try/catch/finally
saying, if anything is caught, sleep and then "exit" (which would continue the while). while
内的第一件事是try/catch/finally
,如果发现任何东西,先入睡,然后“退出”(这会持续一会儿)。
If there was an OutOfMemory
issue outside the thread at a higher level, would the thread just die altogether? 如果在更高级别的线程外存在
OutOfMemory
问题,那么该线程会完全死掉吗? If so, the try/catch/finally
wouldn't catch
because the execution of the OOM is outside that scope? 如果是这样,由于OOM的执行不在该范围内,因此
try/catch/finally
不会catch
?
Would the thread be garbage collected or not (it died ungracefully). 线程是否被垃圾回收(它不合常理地死了)。
TLDR: If a Runnable
gets OutOfMemory
does it die and just stop in its tracks, or is that exception thrown within the scope of the execution? TLDR:如果
Runnable
得到OutOfMemory
它死,只是停止在其轨道上,或者是异常的执行范围之内抛出?
run(){
while(true){
try {
stuff
} catch{ //blah
} finally{sleep}
}
}
When an Error
not an Exception
ocurs the whole JVM -> all Threads will die in most cases. 当
Error
而不是Exception
发生时,整个JVM->在大多数情况下,所有线程都会死亡。
If your background thread doesn't uses shared resurces it MAYBE surives but as said its very uncommon. 如果您的后台线程不使用共享资源,则它可能会正常运行,但正如前所述,这非常罕见。 Ah and if it is an deamon threas it will die instat.
啊,如果这是恶魔般的威胁,它会死掉。
What do you mean with the try catch final? 你说的试射决赛意味着什么? You cannot realy catch an error, it is like a bullet:
您无法真正发现错误,就像子弹头一样:
an error is catchable, you can try to catch but if its thrown you die.
错误是可捕获的,您可以尝试捕获,但是如果抛出该错误,您将死亡。
An OutOfMemoryError
is thrown when an allocation fails. 分配失败时将引发
OutOfMemoryError
。 Therefore, it is passed up the call chain of the thread which made the allocation attempt. 因此,它向上传递进行分配尝试的线程的调用链。 Only
try … catch
blocks encapsulating this invocation chain, resp. 只能
try … catch
封装此调用链的块,分别。 the allocation itself may catch it. 分配本身可能会抓住它。
There is no direct effect on the JVM's overall operation nor other threads. 对JVM的整体操作或其他线程没有直接影响。 Of course, if the reason for throwing an
OutOfMemoryError
is that the JVM is low on memory, there's a chance that this extraordinary condition itself affects the overall JVM operation or other threads at the same time. 当然,如果引发
OutOfMemoryError
的原因是JVM的内存不足,则这种异常情况本身有可能同时影响整个JVM操作或其他线程。 Eg, all threads attempting an allocation at that time may fail with an error. 例如,当时所有尝试分配的线程都可能因错误而失败。
As demonstrated by this answer , multiple threads may encounter the same OutOfMemoryError
instance if the memory is so low that no individual error instances can be constructed. 如该答案所示 ,如果内存太低而无法构造单个错误实例,则多个线程可能会遇到相同的
OutOfMemoryError
实例。 But this does not mean that thrown errors may slosh over to different threads. 但这并不意味着抛出的错误可能会蔓延到不同的线程。 There's still a causal relationship between a failed allocation in a thread and the error being caught within that thread.
线程中的分配失败与该线程中捕获的错误之间仍然存在因果关系。 Or concurrency frameworks may hand over the error instance to an initiating thread if an asynchronous operation failed.
否则,如果异步操作失败,并发框架可能会将错误实例移交给启动线程。
The only reason for a JVM to automatically exit on an OutOfMemoryError
is an indirect one; JVM在
OutOfMemoryError
上自动退出的唯一原因是间接原因。 if all non-daemon threads exited in response to an OutOfMemoryError
, eg when not catching it at all, the JVM will exit because that's the standard behavior when no non-daemon thread is alive. 如果所有非守护程序线程都响应
OutOfMemoryError
退出,例如,当根本不捕获它时,JVM将退出,因为这是没有守护程序线程处于活动状态时的标准行为。
There are scenarios where an application could recover from a single failed allocation when the JVM is not low on memory in general, eg if the failed allocation was extraordinary large (the expression new long[Integer.MAX_VALUE-8]
requires ~16GiB), if it hits general limitations ( new long[Integer.MAX_VALUE]
is not supported by HotSpot, even if there's enough memory), or need special memory rather than ordinary heap space (native buffers, graphics memory or PermGen space in older JVMs). 在某些情况下,通常情况下,当JVM的内存不足时,应用程序可以从单个失败的分配中恢复,例如,如果失败的分配非常大(表达式
new long[Integer.MAX_VALUE-8]
需要〜16GiB),它达到了一般限制(即使有足够的内存,HotSpot也不支持new long[Integer.MAX_VALUE]
),或者需要特殊的内存而不是普通的堆空间(较旧的JVM中的本地缓冲区,图形内存或PermGen空间)。
Homework time again? 再次做作业?
An OutOfMemoryError
is an error, not an exception. OutOfMemoryError
是错误,不是异常。 You could catch an Error
-after all, they derive from Throwable
, as does Exception
- but it's not a very good idea. 您可能会遇到一个
Error
-毕竟它们都是从Throwable
派生的,而Exception
也是如此-但这不是一个好主意。
Your thread doesn't die, your entire JVM does. 您的线程不会死,整个JVM不会死。 Because there's really no graceful way to recover from an
OutOfMemoryError
. 因为实际上没有从
OutOfMemoryError
恢复的优美方法。
When you catch OutOfMemoryError
in your while loop everything you allocated(assuming they are only referenced in your loop) up to the point memory error, will be eligible to garbage collection.(this will also be the case without the error) 当您在while循环中捕获
OutOfMemoryError
,分配给您的所有内容(假设它们仅在您的循环中被引用)直到点内存错误,都可以进行垃圾回收(这也是没有错误的情况)
If a thread dies because of OutOfMemoryError
, its stack will be destroyed and all the object that are referenced from only that stack will also be eligible to garbage collection. 如果线程因
OutOfMemoryError
而死,则其堆栈将被破坏,并且仅从该堆栈中引用的所有对象也将有资格进行垃圾回收。
Even if main thread dies because of OutOfMemoryError
if you have non-daemon threads alive, the jvm will not die. 即使主线程由于
OutOfMemoryError
而死,即使您还存在非守护程序线程,JVM也不会死。
OutOfMemoryError
can have different causes, they are listed here https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/memleaks002.html OutOfMemoryError
可能有不同的原因,它们在这里列出https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/memleaks002.html
Normally It is advised to clean up and exit when you catch OutOfMemoryError
. 通常,建议您在捕获
OutOfMemoryError
时清理并退出。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.