网上搜索了一下,关于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:\test>java -Xms8M -Xmx8M -Xss1K Test 600

dg(600) = 180300

C:\test>java -Xms8M -Xmx8M -Xss1K Test

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

java 线程栈 & java.lang.StackOverflowError的更多相关文章

  1. Java 线程--实现java.lang.Runnable接口实现线程

    Java线程的第一种实现方式,主要分两步,第一步是继承java.lang.Thread; 第二步是重写run()方法.接下来我们来看Java线程的第二种实现方式,也是分为两步,第一步,写一个类实现ja ...

  2. Java虚拟机栈(java stack)

    虚拟机栈(java stack) 百度图片搜索里的动图搜索功能不错,可以搜索一些动图,展示操作数栈的操作过程,比较形象.这点google差点意思 虚拟机栈(jvm stacks)是线程独占的 里面是多 ...

  3. 【Java线程】Java内存模型总结

    学习资料:http://www.infoq.com/cn/articles/Java-memory-model-1 Java的并发采用的是共享内存模型(而非消息传递模型),线程之间共享程序的公共状态, ...

  4. (转)【Java线程】Java内存模型总结

    Java的并发采用的是共享内存模型(而非消息传递模型),线程之间共享程序的公共状态,线程之间通过写-读内存中的公共状态来隐式进行通信.多个线程之间是不能直接传递数据交互的,它们之间的交互只能通过共享变 ...

  5. Java 线程--继承java.lang.Thread类实现线程

    现实生活中的很多事情是同时进行的,Java中为了模拟这种状态,引入了线程机制.先来看线程的基本概念. 线程是指进程中的一个执行场景,也就是执行流程,进程和线程的区别: 1.每个进程是一个应用程序,都有 ...

  6. Java 线程 — JMM Java内存模型

    JMM Java Memory Model,Java内存模型,属于语言级的内存模型 并发编程中存在的问题: 如何通信:用于线程之间交换信息.两种方式:共享内存,消息传递 如何同步:用于控制不同线程间操 ...

  7. 【Java线程】Java线程池ExecutorService

    示例 import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.u ...

  8. 程序员的视角:java 线程(转)

    在我们开始谈线程之前,不得不提下进程.无论进程还是线程都是很抽象的概念,有一个关于进程和线程很形象的比喻能帮我们更好的理解. 进程就像个房子,房子是一个包含了特定属性的容器,例如空间大小.卧室数量等. ...

  9. 程序员的视角:java 线程

    在我们开始谈线程之前,不得不提下进程. 无论进程还是线程都是很抽象的概念,有一个关于进程和线程很形象的比喻能帮我们更好的理解. 进程就像个房子,房子是一个包含了特定属性的容器,例如空间大小.卧室数量等 ...

随机推荐

  1. 我就骂你了,我tm还想打你呢

    从地铁出来,一男的抽烟走在我前面,走了一路闻了一路二手烟. 进门,一个园区的,我直接骂了一句:caoni妈的 这哥们瞪着我,我也瞪着他 你骂我干什么 我闻了一路子二手烟 你可以走前面啊 我不走啊 我不 ...

  2. Fedora 19安装mysql

    安装数据库模块 Mysql和Mysql-server#yum install mysql mysql-server 开启mysql服务#systemctl start mysqld.service同样 ...

  3. 生产者消费者模式 php 【转】

    在工作中常常听到某某大牛之间的交谈会涉及到,xx消费者啊啥的,到底什么大牛之间讲的是什么? 这篇文章主要解决三个问题: 1.到底什么是生产者和消费者,以及它们之间的故事 2.它们之间靠什么交流 3.应 ...

  4. Linux内核分析:期中总结

    第一章:计算机是如何工作的 计算机大部分都是用冯诺依曼体系结构,即存储程序计算机. 两个层面: 1.硬件: cpu(IP寄存器:指针,指向内存的某块区域)——总线——内存(代码与数据) 2.程序员: ...

  5. 第三个Sprint冲刺第3天

    成员:罗凯旋.罗林杰.吴伟锋.黎文衷 组内各成员加紧完成自己的工作.

  6. Oracle10.2.0.1以及其他版本升级Oracle10.2.0.5的简单步骤

    Oracle没有发布 完整版的 Oracle 10.2.0.5 的安装包,只能是通过安装完10.2.0.4 之后再升级10.2.0.5 这一点挺坑的. 建安记录一下步骤. 1. 挂载Oracle10. ...

  7. kali linux升级

    自己使用的是2017.2 版本的kali linux 想着升级一下 里面的包 比如msf 等 但是执行 msfupdate时提示 root@kali201702:~# msfupdate msfupd ...

  8. 日志那点事儿——slf4j源码剖析

    前言: 说到日志,大多人都没空去研究,顶多知道用logger.info或者warn打打消息.那么commons-logging,slf4j,logback,log4j,logging又是什么关系呢?其 ...

  9. jq 事件取消绑定与重新绑定

    前端有时会碰到这样的需求: 点击某个元素发送ajax请求, 发送期间此元素的鼠标相关事件(比如点击)无效, 发送完成鼠标点击事件功能恢复, 对于这种需求, 我们会遇到两种情况, 一种是点击的按钮为fo ...

  10. jdk1.8 HashMap的扩容resize()方法详解

    /** * Initializes or doubles table size. If null, allocates in * accord with initial capacity target ...