我正在尝试复制trying http://msn.com
Success 446035
trying https://google.com
Sucess 234077
trying https://www.nasdaq.com/markets/stocks/symbol-change-history.aspx?sortby=EFFECTIVE&page=1
Traceback (most recent call last):
...
TimeoutError: [WinError 10060] A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond
trying https://yahoo.com
Success 642758
但是使用 -Xss VM参数。
我猜想,如果我们有大量线程,并且每个线程都占用X个堆栈空间,那么如果thread * X>总堆栈大小,我将出现异常。
但是什么也没发生。
我的测试人员:
` 公共静态void main(String [] args)引发异常 {
java.lang.OutOfMemoryError: unable to create new native thread
`
我的VM参数是
-Xms512m -Xmx512m -Xss1g
有人知道为什么我没有例外吗?以及我该如何拒绝?
谢谢
答案 0 :(得分:3)
在大多数OSE上,堆栈是延迟分配的,即,只有您实际使用的页面才变为实际内存。根据所使用的操作系统,每个进程的虚拟内存限制为128到256 TB,因此每个线程1 GB的虚拟内存至少需要128k线程。我会尝试更大的堆栈。例如。 256克
编辑:自己尝试一下,看起来它忽略4g及以上的堆栈大小。在Windows上,最大尺寸为-Xss4000m。
试图在Windows上重现此错误,在抛出任何异常之前,它似乎使计算机超载。
这是我尝试过的。使用-Xss4000m
运行时,它有20多个线程(在我的Windows笔记本电脑停止工作之前,总共有80g)
您可能会在Linux中发现它会在机器过载之前达到ulimit
。
import java.util.concurrent.*;
class A {
public static void main(String[] args) throws InterruptedException {
ThreadPoolExecutor pool = new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<>());
try {
for (int i = 0; i < 100; i++) {
System.out.println(i);
pool.submit(() -> {
try {
System.out.println(recurse() + " size " + pool.getPoolSize());
} catch (Throwable t) {
t.printStackTrace();
}
return null;
});
Thread.sleep(1000);
}
} finally {
pool.shutdown();
}
}
static long recurse() {
try {
return 1 + recurse();
} catch (Error e) {
try {
Thread.sleep(10000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
return 1;
}
}
}