JVM运行时数据区学习总结

jvm学习了有一段时间了,今天来简单的总结一下。

其实,我们平时使用的JRE 或JDK中的JVM都只是某个厂商提供的JVM产品,是对JVM规范的某一个具体实现,由于各个厂商对于JVM有各自不同的实现,所以我们要学习的其实是JVM总体的概念和规范。

我们总是提及JVM,其实JVM的内容很多,我们学习最多的还是它的运行时数据区,今天简单总结的就是这一部分。

运行时数据区分为:方法区、堆、虚拟机栈、程序计数器、本地方法栈。其中方法区、堆是线程共享的,虚拟机栈、程序计数器、本地方法栈是线程私有的。

其中程序计数器部分是jvm规范中规定的唯一不会发生 OOM的地方,这个很多博客和书籍都提到了。那么程序计数器究竟存储的是什么呢?程序计数器保存的是当前线程运行的指令位置,专业的说法是:当前线程所执行的字节码的行号指示器。

为什么需要这样的一块区域来存储这个东西呢?因为java虚拟机的多线程是通过线程轮流切换并分配处理器执行时间的方式来实现的,在任何确定的时刻,一个处理器(一个内核)都只能执行一个线程中的指令。因此当线程切换时,为了切换后能恢复到正确的执行位置,每条线程都需要一个独立的程序计数器,各个线程之间是不互相影响的。

虚拟机栈又是什么呢?

java虚拟机栈描述的是java方法执行时的内存模型,它的生命周期和线程相同。每个方法执行时都会创建一个栈帧,每个方法从调用到执行完成的过程都对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。

那么什么是栈帧呢? 在这里摘抄一个概念吧:栈帧是用于支持虚拟机进行方法调用和方法执行的数据结构,是虚拟机栈的栈元素。既然栈帧是一个数据结构,那么它保存的又是什么数据呢?包括 局部变量表、操作数栈、动态链接、方法返回地址(方法出口)等。这里又出来了一些概念,逐一说一下:

局部变量表:局部变量表是一组局部变量值存储空间,用于存储方法参数和方法内部定义的局部变量。在Java程序编译为Class文件时,就确定了该方法所需要分配的局部变量表的最大容量。

操作数栈:也叫操作栈,是一个后入先出栈。

动态链接:Class文件的常量池中存有大量的符号引用,字节码中的方法调用指令就以常量池中指向方法的符号引用作为参数。这些符号引用有些会在类加载阶段或者第一次使用的时候就转化为直接引用,这种转化称为静态解析。另外一部分将在每一次运行期间转化为直接引用,这部分称为动态链接。

方法返回地址:当一个方法开始执行后只有两种方法可以退出方法:第一种方式是执行引擎遇到任意一个方法返回的字节码指令称为正常完成出口;另一种是方法在执行的过程中遇到了异常,并且这个异常在方法体内没有得到处理,称为异常完成出口。

 

本地方法栈是什么呢?

本地方法栈和虚拟机栈很相似,区别就是:虚拟机栈为虚拟机执行java方法服务,而本地方法栈为虚拟机使用到的Native方法服务。

方法区则是保存虚拟机加载的类信息、静态变量、常量、即时编译器编译的代码等数据。很多人习惯将方法区称为“永久代”,本质上这两者是不一样的,只是因为很多人习惯在HotSpot虚拟机上进行开发,而HotSpot虚拟机的设计团队使用永久代来实现方法区,这样HotSpot的垃圾收集器就能像管理Java堆一样管理方法区这部分内存,这样就能省去一部分专门编写为方法区内存管理的代码的工作,说白了就是懒罢了......(这是JDK1.7以前的设计)

堆:保存对象实例。Java堆是垃圾收集器管理的主要区域。从内存回收的角度来看,由于现在收集器基本都采用分代收集算法,所以Java堆还可以分为新生代和老年代;新生代还可以分为Eden空间、From Servivor空间、To Servivor空间等。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值