【JVM】JVM运行时数据区域

引言:Java虚拟机在执行Java程序的过程中,会把它管理的内存划分为若干个数据区域。这些区域有各自的特点与用途。以下是简图


一,这些数据区域分为两类


1,线程隔离的数据区:这些区域则是依赖用户线程的启动和结束而建立和销毁。

包括:程序计数器,Java虚拟机栈,本地方法栈

特点:Java垃圾回收机制并不关注这个三个区,因为随着线程的结束,内存自然就随着被回收了


2,由所有线程共享的数据区:这些区域随着虚拟机进程的启动而存在。

包括:方法区,堆

特点:Java中的垃圾收集器所关注的就是线程隔离的数据区,即方法区和堆。



二,JVM运行时五个数据区域的主要特点


1,程序计数器(Program Counter Register)

作用:当前线程所执行的字节码的行号指示器

特点:

1)每条线程都有一个独立的程序计数器,互不干扰,独立存储,所以我们称它为“”线程私有“的区域。

2)如果线程正在执行一个java方法,程序计数器记录的是正在执行的虚拟机字节码指令的地址,如果正在执行的是native方法,则计数器值为空。

3)程序计数器是唯一一个Java虚拟机中没有规定任何OutOfMemoryError情况的区域。


2,Java虚拟机栈(Java Virtual Machine Stacks)

作用:描述Java方法执行的内存模型。每个方法被执行时都会创建一个栈帧,栈帧中存储着这个方法的局部变量表等等相关信息,每个方法的栈帧都进栈放到Java虚拟机栈,栈帧进栈对应着方法开始执行,栈帧出栈对应方法执行结束。

特点:

1)平时大家把Java内存区分为堆内存(Heap)和栈内存(Stack),这种方法比较粗糙,其实此处的”栈“就是这里的Java虚拟机栈,或者说是虚拟机栈中的局部变量表部分。

2)每个方法的栈帧分配多大的局部变量空间表示在编译期间确定的,在方法运行期间不会改变局部变量表的大小。

3)这个区域有两种异常

a,StackOverflowError异常:线程请求的栈深度大于虚拟机所允许的深度(不可以动态扩展)

b,OutOfMemoryError异常:虚拟机栈可以动态扩展,扩展时无法申请到足够的内存。


3,本地方法栈(Native Method Stacks)

作用:本地方法栈和虚拟机栈所发挥的作用相同,但是针对的是native方法。

特点:抛出StackOverflowError异常与OutOfMemoryError异常,抛出的原理和虚拟机栈对应的原理相同。


4,Java堆(Java Heap)

作用:此内存的唯一目的就是存放对象实例与数组。(但是随着一些新的技术的发展,比如JIT编译器,逐渐出现了栈上分配等等方式)

特点:

1)垃圾收集器管理的主要区域就是Java堆,Java堆是被所有线程共享的一块内存区域,此内存区域的唯一目的是存放对象实例。

2)Java堆是垃圾收集器管理的主要区域,也是我们常说的“GC堆”,现在收集器基本都是采用分代收集算法,所以Java堆中还可以细分为:新生代和老年代。

3)Java堆不一定要处于物理上的连续状态。只需要是逻辑上连续即可。

4)Java堆可以设置为固定大小或者可扩展的。当前主流的虚拟机都是设置为可扩展的(通过-Xmx和-Xms控制),所以一般情况下Java堆抛出的异常是:OutOfMemoryError异常


5,方法区(Method Area)

作用:存储已被虚拟机加载的类信息,常量,静态变量等数据

特点:

1)和Java堆类似,方法区在物理上可以不连续,可以选择固定大小或者扩扩展。

2)方法区是Java堆的一个逻辑部分,但是可以不实现垃圾回收,垃圾收集行为在这个区域极少出现。但是还是必须适当地进行垃圾回收,主要是针对其中的常量池。


tips:

StackOverflowError异常:线程请求的栈深度大于所允许的深度(不可以动态扩展)

OutOfMemoryError异常:某个区域可以动态扩展,扩展时无法申请到足够的内存(可扩展)


其他

关于运行时常量池以及直接内存,后续再学习。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值