Java程序内存不足,但不是真正的内存不足
我正在IntelliJ中运行我的应用程序,用于此实验,它因以下错误而崩溃:Java程序内存不足,但不是真正的内存不足,java,windows,visualvm,Java,Windows,Visualvm,我正在IntelliJ中运行我的应用程序,用于此实验,它因以下错误而崩溃: java.lang.OutOfMemoryError: unable to create new native thread at java.lang.Thread.start0(Native Method) at java.lang.Thread.start(Thread.java:717) at java.util.concurrent.ThreadPoolExecutor.addWorker
java.lang.OutOfMemoryError: unable to create new native thread
at java.lang.Thread.start0(Native Method)
at java.lang.Thread.start(Thread.java:717)
at java.util.concurrent.ThreadPoolExecutor.addWorker(ThreadPoolExecutor.java:957)
at java.util.concurrent.ThreadPoolExecutor.processWorkerExit(ThreadPoolExecutor.java:1025)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
或
我启动了Java Visual VM,我看到:
错误发生在垂直线附近。我对此感到困惑,因为使用的内存没有接近可用内存,可用内存只有允许的最大内存的一半。此外,在这次练习中,我的计算机实际可用内存超过10GB。这是在Windows 10计算机上运行的
我创建了这个小程序来探索线程的极限:
public class ThreadBlower {
public static void main(String[] args) {
System.out.println("Creating threads until we crash.");
for (int i = 0; ; i++) {
Thread thread = new Thread(() -> { while (true) { } });
thread.setName(String.format("Thread %d", i));
thread.start();
System.out.printf("Running %d threads.%n", i);
}
}
}
尽管它确实因java.lang.OutOfMemoryError而崩溃:无法创建新的本机线程
。我不认为我的应用程序能接近这个数字
你知道这是怎么回事吗
这可能相关,也可能无关:这似乎只发生在Java 32位上,而不是64位上。仅使用32位时也会发生以下情况:
java.lang.OutOfMemoryError:无法创建新的本机线程
可能是由于耗尽文件描述符或操作系统本机线程造成的
如果你在Linux上,你可以运行
$ ulimit -a
要检查您的用户的当前限制,请参见。建议重复:@ErwinBolwidt:我认为这个问题可能非常相关,但我的开发和目标平台都是Windows,所以,这个问题可能有也可能没有不同的技术和/或解决方案。可能您有大量的开放流/连接。您如何知道okhttp3没有创建2700个线程?“你做了一个线程转储吗?”RuStux:我不是真的,但是java VM VM说,生存高峰是67(在屏幕截图的中间)。谢谢你的回答“Karol”。我在Windows 10上运行,因此,我没有
ulimit
。我在问题中添加了一些关于我有多少线程的细节。我不确定Windows的限制是什么。@Timir:虽然我很欣赏Karol的回答,但他的回答主要集中在Linux上,而我遇到的问题是在Windows上。我在问题中添加了更多关于我创建了多少线程的信息,但没有那么多。不要提出ulimit
,以避免出现错误。线程限制已经很大了。改为修复根本问题。@rustyx:首先,我在使用Windows,我的客户也在使用Windows,所以,没有ulimit
;第二,我不能去找每个下载我的应用程序的人,然后更改他们电脑的设置。不过我同意不在Linux服务器上提升ulimit
。@pupeno尽管我不熟悉Windows,但总线程限制将取决于堆栈空间。据我所知,所有Windows进程都将争夺此堆栈空间,因此这可能取决于此计算机上运行的其他程序。
$ ulimit -a