• java 线程栈 & java.lang.StackOverflowError


    网上搜索了一下,关于java的线程栈:

    JDK5.0以后每个线程堆栈大小为1M,以前每个线程堆栈大小为256K.

    JVM的内存,被划分了很多的区域: (来源:http://www.iteye.com/topic/808550)

    1.程序计数器

    每一个Java线程都有一个程序计数器来用于保存程序执行到当前方法的哪一个指令。

    2.线程栈

    线程的每个方法被执行的时候,都会同时创建一个帧(Frame)用于存储本地变量表、操作栈、动态链接、方法出入口等信息。每一个方法的调用至完成,就意味着一个帧在VM栈中的入栈至出栈的过程。如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError异常;如果VM栈可以动态扩展(VM Spec中允许固定长度的VM栈),当扩展时无法申请到足够内存则抛出OutOfMemoryError异常。

    3.本地方法栈

    4.堆

    每个线程的栈都是该线程私有的,堆则是所有线程共享的。当我们new一个对象时,该对象就被分配到了堆中。但是堆,并不是一个简单的概念,堆区又划分了很多区域,为什么堆划分成这么多区域,这是为了JVM的内存垃圾收集,似乎越扯越远了,扯到垃圾收集了,现在的jvm的gc都是按代收集,堆区大致被分为三大块:新生代,旧生代,持久代(虚拟的);新生代又分为eden区,s0区,s1区。新建一个对象时,基本小的对象,生命周期短的对象都会放在新生代的eden区中,eden区满时,有一个小范围的gc(minor gc),整个新生代满时,会有一个大范围的gc(major gc),将新生代里的部分对象转到旧生代里。

    5.方法区 

    其实就是永久代(Permanent Generation),方法区中存放了每个Class的结构信息,包括常量池、字段描述、方法描述等等。VM Space描述中对这个区域的限制非常宽松,除了和Java堆一样不需要连续的内存,也可以选择固定大小或者可扩展外,甚至可以选择不实现垃圾收集。相对来说,垃圾收集行为在这个区域是相对比较少发生的,但并不是某些描述那样永久代不会发生GC(至 少对当前主流的商业JVM实现来说是如此),这里的GC主要是对常量池的回收和对类的卸载,虽然回收的“成绩”一般也比较差强人意,尤其是类卸载,条件相当苛刻。

    6.常量池

     Class文件中除了有类的版本、字段、方法、接口等描述等信息外,还有一项信息是常量表(constant_pool table),用于存放编译期已可知的常量,这部分内容将在类加载后进入方法区(永久代)存放。但是Java语言并不要求常量一定只有编译期预置入Class的常量表的内容才能进入方法区常量池,运行期间也可将新内容放入常量池(最典型的String.intern()方法)。

    今天研究了一下 java 的线程栈,写了一段代码用于测试:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    public class Test
    {
        byte[] data = new byte[8192];
         
        public static void main(String[] args)
        {
            if(args.length == 0)
            {
                System.out.println("确少参数, 正确的命令: java Test <数字>");
                System.exit(0);
            }
             
            int x = Integer.parseInt(args[0]);
             
            //这里不论申请多大的空间,都不会抛出 java.lang.StackOverflowError
            byte[] data = new byte[2048];
             
            //递归的次数与 线程栈 以及 java.lang.StackOverflowError 有直接关系
            System.err.println("dg(" + x + ") = " + dg(x));
        }  
         
        //递归测试
        private static int dg(int x)
        {
            //测试发现这里申明的变量数与线程栈以及java.lang.StackOverflowError有直接关系      
            int a = 1;
            int b = 2;
             
            //这里不论申请多大的空间,都不会抛出 java.lang.StackOverflowError       
            byte[] data = new byte[2048];
             
            if(x > 1)
            {
                return x + dg(--x);
            }
            else
            {
                return x;
            }
        }
    }

    C: est>java -Xms8M -Xmx8M -Xss1K Test 600

    dg(600) = 180300

    C: est>java -Xms8M -Xmx8M -Xss1K Test 700

    Exception in thread "main" java.lang.StackOverflowError

            at Test.dg(Test.java:26)

            at Test.dg(Test.java:34)

            at Test.dg(Test.java:34)

            at Test.dg(Test.java:34)

    2014-03-08

  • 相关阅读:
    女生“不愁嫁”的10大专业,有地位有面子!
    中国南北方文化差异分析比较
    跨代的对决 英特尔i7-6700HQ对比i7-4720HQ性能测试
    差之毫厘谬之千里!带你认识CPU后缀含义
    机器学习及其应用2013, 机器学习及其应用2015
    mysql中替换行首字符
    北京长途汽车站一览表
    IQ一个人的智力和对科学知识的理解掌握程度。 EQ对环境和个人情绪的掌控和对团队关系的运作能力。 AQ挫折商 一个人面对困境时减除自己的压力、渡过难关的能力。
    金融是现代经济的主要行业,因此金融类企业对学历的要求也就高,但同时金融类企业的工资也是比较高的。比如证券业、银行业,这些行业的工资都是处于领先地位的。名校金融毕业生的收入不菲早已不是什么秘密。而且,金融专业毕业生平均起点工资和平均定级工资已位列前端,排在曾经风光无限的IT业等行业之前。
    Basic Authentication in ASP.NET Web API
  • 原文地址:https://www.cnblogs.com/personnel/p/4584929.html
Copyright © 2020-2023  润新知