我有几个jvm参数,但很难理解它们。
谢谢
/**
*VM Args:-Xss512M
*/
public class JavaVMStackOOM{
private void noStop(){
while(true){
}
}
public void stackLeakByThread(){
while(true){
Thread thread=new Thread(new Runnable() {
@Override
public void run() {
noStop();
}
});
thread.start();
}
}
public static void main(String[]args)throws Throwable{
JavaVMStackOOM oom=new JavaVMStackOOM();
oom.stackLeakByThread();
}
}发布于 2019-06-19 09:03:37
1.第一个问题是参数-Xms20m和-Xss2M (第一个是堆大小,第二个是线程堆栈大小),m和M是否有相同的含义,所有的手段都是MB?
是的,M和M的意思相同,所有的意思都是MB。
2.第二个问题是,我有下面的代码片段,由于堆栈大小被设置为512米,所以我希望很快得到一个运行时错误,但是代码会导致我的操作系统卡住,永远不会给我运行时错误,有人知道为什么吗?
首先,Java不仅仅使用堆内存。JVM在某些情况下使用非堆内存(调用tack、Metaspace等)。这个问题回答这个情况。因此,线程堆栈使用非堆内存。
证明:
运行应用程序XX:NativeMemoryTracking=summary并使用jcmd VM.native_memory命令检查已使用的内存。相关的javadoc 这里。
首先,使用-XX:NativeMemoryTracking=summary -Xms20m -Xss2M参数和结果运行应用程序:
本机内存跟踪: 共计: reserved=4581409KB、committed=171605KB
然后,使用java -XX:NativeMemoryTracking=summary -Xms20m -Xss512M参数和结果运行相同的应用程序:
本机内存跟踪: 共计: reserved=7714849KB、committed=3305045KB
正如您所看到的,堆内存在这两种情况下都没有改变,但是线程本机内存与最后一种情况一起增加。因为我们增加了每个堆栈的大小。因此,应用程序从不提供运行时错误,因为堆栈不使用堆内存。
注意:保留内存代表了应用程序可能使用的内存总量。相反,提交的内存等于我们的应用程序现在使用的内存数量。
注2:对于每个线程,JVM创建一个运行时堆栈,存储在这里。该堆栈的每个块称为激活记录/堆栈帧,用于存储方法调用。该方法的所有局部变量都存储在相应的帧中。线程终止后,它的运行时堆栈将被JVM销毁。这不是一个共享的资源。
发布于 2019-06-19 11:23:27
M和M的意思是一样的。
StackSize设置为每个线程。因此,要超过512 So的限制,您需要创建一个非常大的局部变量。不是堆上要引用的东西.
Xss通常按几KB的顺序设置,以说明大堆栈,在堆栈帧上的每个方法中都有一些东西,如计数器等。如果您想要突破这个限制,最好编写一个无限递归,其中每个方法分配几个局部变量。
public class JavaVMStackOOM{
public void stackLeakByThread(long i){
stackLeakByThread(i+1);
}
}
public static void main(String[]args)throws Throwable{
JavaVMStackOOM oom=new JavaVMStackOOM();
oom.stackLeakByThread(0l);
}
}在这种情况下,每个方法都将在堆栈上存储一个长变量。如果您的堆栈足够深,您将超过Xss限制。
https://stackoverflow.com/questions/56661193
复制相似问题