Java 使用-Xss复制OutOfMemoryError
我正在尝试重现Java 使用-Xss复制OutOfMemoryError,java,exception,jvm,out-of-memory,Java,Exception,Jvm,Out Of Memory,我正在尝试重现java.lang.OutOfMemoryError:无法创建新的本机线程 但是使用-XssVM参数。 我猜如果我们有大量线程,并且每个线程占用X个堆栈空间,那么如果线程*X>总堆栈大小,我会有一个例外。 但什么也没发生 我的测试人员: ` 公共静态void main(字符串[]args)引发异常 { ThreadPoolExecutor executor=新的ThreadPoolExecutor(1000,15000,0L,TimeUnit.ms, 新建LinkedBlockin
java.lang.OutOfMemoryError:无法创建新的本机线程
但是使用-XssVM参数。
我猜如果我们有大量线程,并且每个线程占用X个堆栈空间,那么如果线程*X>总堆栈大小,我会有一个例外。
但什么也没发生
我的测试人员:
`
公共静态void main(字符串[]args)引发异常
{
ThreadPoolExecutor executor=新的ThreadPoolExecutor(1000,15000,0L,TimeUnit.ms,
新建LinkedBlockingQueue());
int i=0;
尝试
{
睡眠(100);
对于大多数操作系统上的(;i),堆栈是延迟分配的,即只有您实际使用的页面会转换为实际内存。根据您使用的操作系统,每个进程的虚拟内存限制为128到256 TB,因此每个线程至少需要128k个线程。我会尝试更大的堆栈。例如256g
编辑:我自己尝试一下,它似乎忽略了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;
}
}
}
import java.util.concurrent.*;
甲级{
公共静态void main(字符串[]args)引发InterruptedException{
ThreadPoolExecutor pool=新的ThreadPoolExecutor(0,Integer.MAX_值,
60升,时间单位。秒,
新建SynchronousQueue());
试一试{
对于(int i=0;i<100;i++){
系统输出打印LN(i);
pool.submit(()->{
试一试{
System.out.println(recurse()+“size”+pool.getPoolSize());
}捕获(可丢弃的t){
t、 printStackTrace();
}
返回null;
});
睡眠(1000);
}
}最后{
pool.shutdown();
}
}
静态长递归(){
试一试{
返回1+recurse();
}捕获(错误e){
试一试{
睡眠(10000);
}捕捉(中断异常e1){
e1.printStackTrace();
}
返回1;
}
}
}
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;
}
}
}