Java 虚拟机初识-运行时数据区

 


《深入理解JAVA虚拟机 3》


二. 运行时数据区

Java虚拟机在执行Java程序的过层中会把它所管理的内存划分成若干个不同的数据区域。这些区域各有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而一致存在,有的依赖用户线程的启动和结束而建立和销毁。

组要分成以下几类:

1.程序计数器

(Program Counter Register)是一个较小的内存空间,可以看做是当前线程所执行的字节码的行号指示器。每个线程都需要一个单独的程序计数器,所以是线程私有。此区域是唯一一个不会出现OutOfMemoryError情况的区域。

 

2.Java虚拟机栈

也是线程私有。它的生命周期和线程相同。它描述的是Java方法执行的线程内存模型,每方法执行的时候,Java虚拟机就会同步创建一个栈帧,每个方法被调用直至执行完毕的过程,就对应着一个栈帧在虚拟机中从入栈到出栈的过程。

  1. 如果线程请求的栈深度大于虚拟机栈为虚拟机锁允许的最大深度,将会抛出StackOverflowError异常;

  2. 如果栈扩展的时候无法申请到足够的内存,将会抛出OutOfMemoryError异常。

 

3.本地方法栈

本地方法栈与虚拟机栈发挥的作用类似,区别是虚拟机栈是为所执行Java方法(字节码)服务,本地方法栈是我虚拟机使用的本地方法(Native)服务。

本地方法栈也会在栈深度和栈扩展失败后分别抛出

StackOverflowError异常,OutOfMemoryError异常。

 

4.Java堆

线程共享。

Java堆(Java Heap)是虚拟机所管理的内存中最大的一块,此内存的唯一目的是存放对象实例,几乎所有的对象实例都是堆里分配内存。

Java堆是垃圾收集器管理的内存区域,因为也被称为GC堆(Garbage Collected Heap)

Java堆可以处于物理上不连续的内存空间,但是在逻辑上它应该是被视为连续的。

Java堆既可以被实现成固定的也可以是扩展的(参数:-Xmx和 -Xms)

如果Java堆中没有内存完成实例分配,并且堆也无法再次扩展,Java虚拟机将会抛出OutOfMemoryError异常。

 

5.方法区

线程共享。

(Method Area)用于存储已被虚拟机加载的类型信息、常亮、静态变量、即使编译器编译后的代码缓存等数据。

JDK8以前被称为”永久代“,JDK8以后废弃永久代概念,用元空间(Metaspace)代替;

和Java堆一样不需要连续的内存空间以及可以股东或者扩展大小,还可以选择不实现垃圾收集。

如果无法满足新的内存分配需求,将会抛出OutOfMemoryError异常。

 

6.运行时常量池

运行时常量池(Runtime Constant Pool)是方法区的一部分;

保存常量池表,存放编译期生成的各种字面量与符号引用,这部分内存将在类加载后存放当方法区的运行时常量池中。

运行时常量池具有动态性,常亮不一定要编译期才能产生,运行期也可以将新的常量放入池中,比如String类的intern()方法。

因为属于方法区的一部分,所以也受到方法区内存的限制,当无法申请到内存时,会抛出OutOfMemoryError异常。

 

7.直接内存

直接内存(Direct Memory),并不是虚拟机运行时数据区的一部分,但也会导致OutOfMemoryError异常的出现.

在JDK1.4以后新加入的NIO(New Input/Output)类,引入一种基于通道(channel)和缓冲区(buffer)的I/O方式,它可以使用Native函数库直接分配内存,然后通过一个存储在Java堆里面的DirectByteBuffer对象作为这块内存的引用进行操作。

本机内存的分配不受Java堆大小的限制,但是收到本机总内存以及处理器寻址空间的限制;

如果忽略此处内存,设置的虚拟机参数可能会导致各个内存区域总和大于物理内存限制,抛出OutOfMemoryError异常。

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值