简体   繁体   English

Java可运行的内存不足

[英]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.

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