109-多线程与JVM内存结构的关系,虚拟机栈实验
Java内存结构-简:
栈(非堆)
堆
栈存储基本数据类型,引用类型
堆存储对象
Java内存结构
栈内存
- 方法区(线程共享)
- 虚拟机栈(线程私有)
栈针(若干):局部变量表、操作栈、动态链接库、方法出口/入口- 本地方法区C++:执行引擎、本地库接口
.so
、本地方法
- 本地方法区C++:执行引擎、本地库接口
- 程序计数器
堆内存
- 对象实体(栈只保存变量的引用)
不断压栈操作将会导致栈溢出,从而程序崩溃并抛出java.lang.StackOverflowError
Java多线程与内存堆栈关系。虚拟机栈
main主线程。
public class CreateThread3 { private static int counter = 0; // JVM will create a thread named "main" public static void main(String[] args) { // create a JVM stack try { add(0); } catch (Error e) { e.printStackTrace();// java.lang.StackOverflowError System.out.println(counter);// 21325 } } private static void add(int i) { counter++; add(i + 1); } }
用户子线程
public class CreateThread4 { private static int counter = 0; public static void main(String[] args) { Thread t = new Thread(new Runnable() { @Override public void run() { try { add(0); } catch (Error e) { e.printStackTrace();// java.lang.StackOverflowError System.out.println(counter);// 18455 } } private void add(int i) { counter++; add(i + 1); } }); t.start(); } }
通过stackSize构造方法改变线程的栈内存大小,避免抛出java.lang.StackOverflowError
。但是JVM启动时创建的栈空间不变,由于线程的栈空间占用了很大虚拟机栈内存,所以在main主线程里,JVM能允许创建的线程数也会相应减少。
public class CreateThread4 {
private static int counter = 0;
public static void main(String[] args) {
Thread t = new Thread(null, new Runnable() {
@Override
public void run() {
try {
add(0);
} catch (Error e) {
e.printStackTrace();
System.out.println(counter);
}
}
private void add(int i) {
counter++;
add(i + 1);
}
}, "stackSizeTest", 1 << 24);
t.start();
}
}
扩展:
编写一个抛出
java.lang.StackOverflowError
的例子编写一个抛出
java.lang.OutOfMemoryError
的例子StackOverFlowError一般是由于栈深度大于虚拟机提供的最大栈深度导致的
OutOfMemoryError一般是由于虚拟机在扩展堆栈时无法申请到足够的内存,可以通过
--xms
和--xmx
来设定虚拟机的最大可扩展内存JVM之–Java内存结构
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 tuyrk@qq.com
文章标题:109-多线程与JVM内存结构的关系,虚拟机栈实验
文章字数:550
本文作者:神秘的小岛岛
发布时间:2019-11-12, 16:35:42
最后更新:2019-12-24, 16:19:52
原始链接:https://www.tuyrk.cn/wang-thread/109-thread-with-memory/版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。