109-多线程与JVM内存结构的关系,虚拟机栈实验

Java内存结构-简:

  • 栈(非堆)

  • 栈存储基本数据类型,引用类型
    堆存储对象

Java内存结构

  • 栈内存

    1. 方法区(线程共享)
  1. 虚拟机栈(线程私有)
    栈针(若干):局部变量表、操作栈、动态链接库、方法出口/入口
    1. 本地方法区C++:执行引擎、本地库接口.so、本地方法
  2. 程序计数器
  • 堆内存

    1. 对象实体(栈只保存变量的引用)

不断压栈操作将会导致栈溢出,从而程序崩溃并抛出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();
    }
}

扩展:

  1. 编写一个抛出java.lang.StackOverflowError的例子

  2. 编写一个抛出java.lang.OutOfMemoryError的例子

    StackOverFlowError一般是由于栈深度大于虚拟机提供的最大栈深度导致的

    OutOfMemoryError一般是由于虚拟机在扩展堆栈时无法申请到足够的内存,可以通过--xms--xmx来设定虚拟机的最大可扩展内存

  3. JVM之–Java内存结构

    JVM之—Java内存结构(第一篇)

    JVM之—Java内存结构(第二篇)

    JVM之—Java内存结构(第三篇)

    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" 转载请保留原文链接及作者。

目录
×

喜欢就点赞,疼爱就打赏