【问题标题】:Java program running out of RAM but not reallyJava 程序内存不足但不是真的
【发布时间】:2018-04-19 08:40:16
【问题描述】:

我在 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(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.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.execute(ThreadPoolExecutor.java:1378)
    at okhttp3.Dispatcher.enqueue(Dispatcher.java:130)
    at okhttp3.RealCall.enqueue(RealCall.java:100)
    at retrofit2.OkHttpCall.enqueue(OkHttpCall.java:107)
    at com.pubnub.api.endpoints.Endpoint.async(Endpoint.java:127)
    at com.pubnub.api.managers.SubscriptionManager.startSubscribeLoop(SubscriptionManager.java:275)
    at com.pubnub.api.managers.SubscriptionManager.access$400(SubscriptionManager.java:31)
    at com.pubnub.api.managers.SubscriptionManager$5.onResponse(SubscriptionManager.java:324)
    at com.pubnub.api.managers.SubscriptionManager$5.onResponse(SubscriptionManager.java:275)
    at com.pubnub.api.endpoints.Endpoint$1.onResponse(Endpoint.java:201)
    at retrofit2.OkHttpCall$1.callSuccess(OkHttpCall.java:138)
    at retrofit2.OkHttpCall$1.onResponse(OkHttpCall.java:117)
    at okhttp3.RealCall$AsyncCall.execute(RealCall.java:153)
    at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)

我启动了 Java Visual VM,这就是我所看到的:

错误发生在垂直线附近。我对此感到困惑,因为已用内存没有接近可用内存,可用内存仅为允许的最大值的一半左右。另外,在这个练习中,我的电脑有超过 10GB 的实际可用 RAM。这是在 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: unable to create new native thread 而崩溃,但它还是需要大约 2700 个线程才能到达那里。我认为我的应用不会接近这个数字。

有什么想法吗?

这可能或可能不相关:这似乎只发生在 Java 32 位而不是 64 位。也只有 32 位会发生这样的情况:EXCEPTION_ACCESS_VIOLATION on "JavaFX Application Thread"

【问题讨论】:

  • @ErwinBolwidt:我认为这个问题可能非常相关,但我的开发和我的目标平台都是 Windows,因此,可能有也可能没有不同的技术和/或解决方案。
  • 也许您有大量打开的流/连接。
  • 你怎么知道okhttp3没有创建2700线程?你做了线程转储吗?
  • @rustyx:我不是真的,但是 Java Visual VM 说 Live Peak 是 67(它在屏幕截图的中间)。

标签: java windows visualvm


【解决方案1】:

java.lang.OutOfMemoryError: unable to create new native thread 可能是由文件描述符或操作系统本机线程耗尽引起的。

如果你在 Linux 上,你可以运行

$ ulimit -a

根据man ulimit 检查您的用户的当前限制。

【讨论】:

  • 感谢@Karol 的回答。我在 Windows 10 上运行,所以对我来说没有ulimit。我添加了一些关于我有多少线程的细节。我不确定 Windows 的限制是什么。
  • @Timir:虽然我很欣赏 Karol 的回答,但他的回答侧重于 Linux,而我遇到的问题是在 Windows 上。我在关于我正在创建多少个线程的问题中添加了更多信息,但并没有那么多。
  • 不要提出ulimit 以避免错误。线程限制已经很大了。改为修复根本问题。
  • @rustyx:首先,我使用的是 Windows,我的客户也是如此,所以,没有ulimit;其次,我不能去找每个下载我的应用程序的人并更改他们的计算机设置。我同意虽然不在 Linux 服务器上提高 ulimit
  • @pupeno 虽然我不熟悉 Windows this answer 建议总线程限制将取决于堆栈空间。据我了解,所有 Windows 进程都会竞争这个堆栈空间,因此它可能取决于这台机器上正在运行的其他内容。
猜你喜欢
  • 2012-08-30
  • 1970-01-01
  • 1970-01-01
  • 2016-03-18
  • 2014-10-15
  • 1970-01-01
  • 1970-01-01
  • 2020-06-27
  • 1970-01-01
相关资源
最近更新 更多