JVM运行时数据区结构

我们编写好的java类是一个.java后缀的文本文件,编译后生成.class后缀的字节码文件,然后再通过ClassLoader类加载器加载到java虚拟机内部后,由执行引擎执行我们的代码。JVM需要有一个内存空间存放所有的类或者对象。那么JVM在程序运行时是如何来分配虚拟机内存,或者说是如何在内存空间中划分空间组织管理我们的数据的呢?这就涉及到运行时数据区的结构问题,首先看下面这张图。

运行时数据区
​JVM运行时数据区

不同的jvm对内存的划分和管理机制存在差异,我们这里介绍的是HotSpot VM

介绍一下这个图,运行时数据区当中,红色的两个部分是方法区和堆,这两块区域在jvm中是所有的线程共享的,而绿色的程序计数器、本地方法栈、java虚拟机栈,这三块空间是每个线程独有的。

方法区用于存储已被虚拟机加载的类型信息、常量、静态变量、即时编译器编译后的代码缓存等数据。

说到方法区就不得不说一下“永久代”,在其他的JVM当中是不存在永久代这个概念的。仅仅是因为在HotSpot的JVM当中,并且实在JDK1.8之前的JVM当中,使用永久代来实现方法区而已,这样使得 HotSpot的垃圾收集器能够像管理Java堆一样管理这部分内存,省去专门为方法区编写内存管理代码的工作。在《java虚拟机实现规范》当中,只是说需要实现方法区,但对于如何实现方法区并没有做约束。但后来出现了永久代导致了Java应用更容易遇到内存溢出的问题。考虑到HotSpot未来的发展,在JDK 6的时候HotSpot开发团队就有放弃永久代,逐步改为采用本地内存(Native Memory)来实现方法区的计划了,到了JDK 7的HotSpot,已经把原本放在永久代的字符串常量池、静态变量等移出,而到了JDK 8,终于完全废弃了永久代的概念,改用与JRockit、J9一样在本地内存中实现的元空间(Meta-space)来代替,把JDK 7中永久代还剩余的内容(主要是类型信息)全部移到元空间中。所以从JDK8以后,元空间就是方法区在HotSpot jvm 中的实现,主要用于存储类的信息、常量池、方法数据、方法代码等。不过元空间与永久代之间最大的区别在于:元空间并不在虚拟机中,而是使用本地内存,其大小理论上取决系统可用虚拟的内存大小。

此内存区域的唯一目的就是存放对象实例,Java 世界里几乎”所有的对象实例都在这里分配内存。Java堆是垃圾收集器管理的内存区域。Java堆既可以被实现成固定大小的,也可以是可扩展的,不过当前主流的Java虚拟机都是按照可扩 展来实现的(通过参数-Xmx-Xms设定)。如果在Java堆中没有内存完成实例分配,并且堆也无法再 扩展时,Java虚拟机将会抛OutOfMemoryError异常。

程序计数器当前线程所执行的 字节码的行号指示器。字节码解释器工作时就是通过改变这个计数器 的值来选取下一条需要执行的字节码指令,它是程序控制流的指示器,分支、循环、跳转、异常处 理、线程恢复等基础功能都需要依赖这个计数器来完成。如果线程正在执行的是一个Java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址;如果正在执行的是本地(Native)方法,这个计数器值则应为空(Undefined)。此内存区域是唯 一一个在《Java虚拟机规范》中没有规定任何OutOfMemoryError情况的区域。

Java虚拟机栈每个方法被执行的时候,Java虚拟机都 会同步创建一个栈帧Stack Frame)用于存储局部变量表、操作数栈、动态连接、方法出口等信 息。每一个方法被调用直至执行完毕的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。

这里说一下局部变量表,它是存放的是编译期间可知的各种Java基本数据类型、对象引用和返回地址。这些数据在局部变量表中都是以slot的方式来表示的。其中64bit的long和double类型会占用两个slot,其他的数据类型都只占用一个slot。局部变量表需要多大的空间(多少slot)是在编译期间就已经决定了的,后期不会再改变。具体这里的一个slot的大小到底是多大,这个与具体的jvm实现有关系,不同的jvm的大小有差异。

本地方法栈:它虚拟机栈所发挥的作用是非常相似的,其区别只是虚拟机 栈为虚拟机执行Java方法(也就是字节码)服务,而本地方法栈则是为虚拟机使用到的本地(Native) 方法服务(非java语言的方法)。

jdk8以后的HotSpot JVM运行时数据区

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值