Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/338.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么这个小Java程序使MacOS重新启动?_Java_Multithreading_Macos_Operating System - Fatal编程技术网

为什么这个小Java程序使MacOS重新启动?

为什么这个小Java程序使MacOS重新启动?,java,multithreading,macos,operating-system,Java,Multithreading,Macos,Operating System,代码如下 Set<Thread> threads = new HashSet<>(); Runnable r = () -> { try { Thread.sleep(Long.MAX_VALUE); } catch (InterruptedException e) { e.printStackTrace(); } }; for (int i = 0; i < 20000; i++) { Th

代码如下

Set<Thread> threads = new HashSet<>();

Runnable r = () -> {
    try {
        Thread.sleep(Long.MAX_VALUE);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
};

for (int i = 0; i < 20000; i++) {
    Thread t = new Thread(r);
    threads.add(t);
    t.start();
    if (i % 100 == 0) {
        System.out.println(i);
    }
    Thread.sleep(2);
}
正如预期的那样,直到我看到:

3900
4000
Exception in thread "main" 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 App.main(scratch.java:24)
Java HotSpot(TM) 64-Bit Server VM warning: Exception java.lang.OutOfMemoryError occurred dispatching signal SIGINT to handler- the VM may need to be forcibly terminated
但过了一会儿(10-20秒左右),MacOS决定重启。我在这里看到的重启原因是什么?主线程抛出异常,但进程有约4000个线程睡眠导致。。。操作系统中有什么?这是内存溢出还是和操作系统的任务调度程序有关

MacOS version: 10.14.3 (18D109)
java version "1.8.0_202"
Java(TM) SE Runtime Environment (build 1.8.0_202-b08)
Java HotSpot(TM) 64-Bit Server VM (build 25.202-b08, mixed mode)

很可能是因为您没有给JVM足够的内存,或者您的计算机硬件和macOS组合不允许同时激活那么多线程。这个问题并不局限于macOS,但是一些Linux发行版,例如Bodhi Linux,也有这个限制。不要被“OutOfMemoryError”所欺骗-这通常意味着JVM无法分配本机线程。

尽管控制台显示程序已完成,JVM进程仍会运行,直到释放所有资源。同时,您的操作系统线程不足,速度慢且不稳定,这会导致所有进程(包括JVM终结)都出现滞后。为了自卫,操作系统触发了内核恐慌。这就是MacOS重新启动的原因


*操作系统-操作系统这是一个变体。这可能会导致严重的速度减慢,但任何用户程序都不应该能够使操作系统崩溃。这可能是操作系统中的错误或内存错误。尝试运行内存检查?

Java是在90年代构建的,当时只有多核处理器

当然,Java已经进化了,现代处理器也是如此。现在我们有8核处理器,具有大缓存(例如:12MB)

尽管并发处理已经有了很大的发展,Java仍然是围绕单核处理器模型设计的。但是,历史已经足够了,让我非常简单地解释一下发生了什么

仅仅通过在Java中创建一个新线程,我们就浪费了大量内存

根据您的JVM版本,每个线程消耗约512KB-1MB(请参阅和)。记住这一点,当持续创建新线程时,在某个时刻它们将消耗堆的所有内存

现在,我从未单独尝试过,但我假设您的计算机的操作系统由于“内存不足”错误而关闭/重新启动,作为一种对策。(这与Windows上臭名昭著的“蓝屏死亡”非常相似,在Windows上,机器需要重新启动以重置CPU状态)


一种可能的解决方案是手动设置JVM使用的最大堆大小。因此,当您的程序完全使用预先分配的堆时,它不会导致关机。请参考关于如何做的问题。

我今天偶然发现了同样的问题。下面是一些在10.15.5(Catalina)上触发相同内核恐慌的python代码。在两台Mac电脑上测试,以确保这不是硬件问题:


也许我会去写一份bug报告。

如果应用程序崩溃了,问题也不会那么大。但是,如果一个程序能够触发系统重启,这是一个严重的与安全相关的操作系统错误(但也可能是一个硬件问题,例如内存问题-不要为每一个故障都归咎于操作系统)。我的安卓手机无法重新启动。我刚收到一个OOM错误。@Carcigenicate这就是我在MacOS上特别注意到的原因。我认为它更多地与这个程序运行的底层操作系统相关,而不是JVM本身。我认为它只能在MacOS中复制。(我不能尝试Windows,因为我手头没有Windows机器。)可以确认它在MacOS Mojave上崩溃,java版本“1.8.0_202-ea”在Windows 10上似乎没有崩溃(尽管我使用了另一台机器)。哈哈。在10万线程时,我得到了一个蓝色的死亡屏幕,它重新启动。也许这算是重新启动?我不认为
不允许那么多线程同时处于活动状态
不是重新启动的原因。如果这是一个“不允许”的问题,那就不是这样的问题了。在ops的情况下,这种情况不会发生,操作系统的“不允许”会以某种方式被绕过,出现操作系统本身中断的情况。这是一个严重的安全问题:一个没有特权的用户(至少在进程隔离方面)能够触发一个有特权的操作。我想知道如果以较低的优先级运行程序,同时将程序中的线程优先级设置为最低,会发生什么情况。
MacOS version: 10.14.3 (18D109)
java version "1.8.0_202"
Java(TM) SE Runtime Environment (build 1.8.0_202-b08)
Java HotSpot(TM) 64-Bit Server VM (build 25.202-b08, mixed mode)