3 回答

TA贡献1942条经验 获得超3个赞
即使异常名称强烈建议也不是内存问题,而是操作系统资源问题。您用完了本机线程,即操作系统将允许您的JVM使用多少线程。
这是一个不常见的问题,因为您很少需要那么多。您是否有很多无条件线程产生,这些线程应该在哪里出现但未完成?
您可能会考虑尽可能在执行器的控制下重写为使用Callable / Runnables。有许多行为可以由您的代码轻松控制的标准执行程序。
(有许多原因限制了线程数,但是它们因操作系统而异)

TA贡献1906条经验 获得超3个赞
在负载测试期间遇到了相同的问题,原因是由于JVM无法进一步创建新的Java线程。以下是JVM源代码
if (native_thread->osthread() == NULL) {
// No one should hold a reference to the 'native_thread'.
delete native_thread;
if (JvmtiExport::should_post_resource_exhausted()) {
JvmtiExport::post_resource_exhausted(
JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR |
JVMTI_RESOURCE_EXHAUSTED_THREADS,
"unable to create new native thread");
} THROW_MSG(vmSymbols::java_lang_OutOfMemoryError(), "unable to create new native thread");
} Thread::start(native_thread);`
根本原因:当JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR(资源耗尽(意味着内存耗尽))或JVMTI_RESOURCE_EXHAUSTED_THREADS(线程耗尽)时,JVM引发此异常。
在我的情况下,Jboss创建了太多线程来满足请求,但是所有线程都被阻塞了。因此,JVM耗尽了线程和内存(每个线程都保存了memory,因为每个线程都被阻塞,所以不释放内存)。
分析Java线程转储后,发现有将近61K线程被我们的方法之一阻塞,这导致了此问题。以下是线程转储的一部分
"SimpleAsyncTaskExecutor-16562" #38070 prio=5 os_prio=0 tid=0x00007f9985440000 nid=0x2ca6 waiting for monitor entry [0x00007f9d58c2d000]
java.lang.Thread.State: BLOCKED (on object monitor)

TA贡献2011条经验 获得超2个赞
您的操作系统可能不允许您尝试创建的线程数,或者您在JVM中达到了一定的限制。特别是如果它是一个32k的整数,则很可能是一种或另一种限制。
您确定您确实需要32k线程吗?大多数现代语言都对可重用线程池提供了某种支持-我确定Java也已经具备了一些功能(例如ExecutorService
,如用户Jesper所述)。也许您可以从这样的池中请求线程,而不是手动创建新线程。
添加回答
举报