为什么这个小型Java程序会重启MacOS?

Kor*_*gay 48 java macos multithreading 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++) {
    Thread t = new Thread(r);
    threads.add(t);
    t.start();
    if (i % 100 == 0) {
        System.out.println(i);
    }
    Thread.sleep(2);
}
Run Code Online (Sandbox Code Playgroud)

执行时,我开始看到像这样的值

0
100
200
300
Run Code Online (Sandbox Code Playgroud)

正如所料,直到我看到:

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
Run Code Online (Sandbox Code Playgroud)

但过了一会儿(10 - 20秒左右),MacOS决定重启.我在这里看到重启的原因是什么?主线程抛出异常,但是有大约4000个线程休眠的进程导致...操作系统中有什么?这是内存溢出还是与OS的任务调度程序有关?

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)
Run Code Online (Sandbox Code Playgroud)

Bad*_*aro 7

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

*操作系统 - 操作系统


Sin*_*ani -4

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

  • 我不认为“不允许多个线程同时处于活动状态”不是重新启动的原因。 (6认同)
  • 如果它是“不允许”,那就不是这样的问题。在操作的情况下,这种情况不会发生,操作系统的“不允许”以某种方式被绕过,并且出现操作系统本身崩溃的情况。这是一个严重的安全问题:非特权用户(至少在进程隔离方面)能够触发特权操作。 (3认同)