【深入理解JVM】-运行时数据区域详解

文章目录

程序计数器

Java 虚拟机栈

局部变量表

本地方法栈

方法区

常量池

直接内存


程序计数器

特点 : 每一个线程都有的,占用的内存很小,运行的速度十分快,没有内存溢出的风险。
作用 : 程序中有多个线程,每一个线程都会抽取一定的时间片来运行,该时间片运行结束就由其他线程来继续运行,每个线程都有一个程序计数器,它就用来当线程运行结束时指向结束位置所指向的字节码运行到的位置,当下一个时间段该线程继续运行时可以在原本的字节码位置继续走下去。当程序中有 while 循环, for 循环, switch if 等语句时可以一步一步指向运行时的下一个位置。
异常 : 没有异常。

Java 虚拟机栈

特点 : 每个线程都有栈,栈的空间在编译的时候已经确定好了。
栈针 : 虚拟机栈是由栈针为单位组成的,当方法执行的时候就入栈,当方法执行结束的时候就出栈。
异常 : Stack Overflow 异常是由于,方法过多导致栈针数超过了栈所能承受最大容量导致的,用 xss 可以设置栈深度的大小。Out of memerry,有的虚拟机中的虚拟机栈是动态可扩展的,所以及时方法再多也不会发生 Stack Overflow ,而是会由于方法过多扩展内存,超过了系统最大内存的容量导致 Out of memerry 。Out of memerry 异常是由于系统内存不够,当编译时为栈分配内存的时候无法为栈分配对应的内存导致的。

局部变量表

特点: 每一个栈针都有局部变量表。
存储内容 : 存当前的方法中的基本数据类型,还有符号引用(reference,指向具体的方法实例和类变量)。
存储: 一个 slot 占用 32 位的空间,存储一般类型的数据,当类型为 long double 时需要用两个 slot 单位来存储。局部变量表的大小(也就是 slot 的个数,每个 slot 的容量不同的系统对应不同的值这个没有办法确定)在编译的时候已经确定好的。

本地方法栈

特点 : 同虚拟机栈,存的是本地方法的内容,具体的结构因为没有强行的规定,由各自的虚拟机自行实现。
异常 : 同虚拟机栈 。

特点: 多个线程共有的,内存是动态分配的,主要存储对象实例和数组。堆的内存按照垃圾收集的方式划分分为新生代(eden 区, suvivor 区),老年代。按照线程方式分,每一个线程都有对应的一个私有的堆内存。
异常: Out of memerry 异常,一直创建新的对象,堆内存不够就动态扩展,直到系统内存也装不下就会报异常。

方法区

特点: 所有栈共享的,内存动态分配的。
存储内容: 类信息,静态变量,常量,class 中缓存的数据。
内存: jdk8 之前用永久代实现的方法区,目的是不用写单独的内存管理方法,直接用堆的垃圾回收就好了,容易发生内存溢出,jdk7 的时候把常量池,静态变量从永久代移动到 了堆区,jdk8 之后用元空间实现的方法区,内存由系统的直接内存提供,不在容易发生内存溢出。
垃圾收集: 方法区一般不进行垃圾回收的,因为卸载一个类需要十分严格的要求。
异常: Out of memerry 异常,方法区一直存类变量等数据,当超过了方法区原本设定的范围就会动态扩展,找到系统内存也装不下就会报异常。

常量池

特点: 是方法区的一部分。
存储内容: 存编译时的数据:class 中的各种字段、符号引用、和符号引用转化的直接引用。运行时的数据:指的是 string intern 方法。
异常: 见常量池异常。

直接内存

存的是 io 流缓冲区,不是运行时数据区的一部分。是由直接内存使用 native 变量进行内存分配的,由堆区中的 DirectByteBuffer 变量操纵,因为要经常和堆进行数据交换,DirectByteBuffer 就很好的解决了这方面的开销
异常 : Out of memerry 异常:由于分配内存的时候系统内存都用来划分堆内存和方法区内存,总是忽略直接内存的内存分配情况,导致直接内存太小发生异常。
        
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值