美文网首页jvm
jvm 运行时数据区-01

jvm 运行时数据区-01

作者: 愤怒的奶牛 | 来源:发表于2019-08-16 16:47 被阅读0次
    1. jvm 运行时数据区
    jvm运行时数据区.png

    jvm 运行时数据区 ,将内存划分为5个区域,java 代码在运行时 类里面的 组成部分 分布在这几个区中。下面先解释一下 这5个区分别时什么意思,然后再和我们的java 代码对比一下,看每个部分都在 哪些区域里面。以先解释均来自网络和书籍。

    • 方法区(线程共享区)

    方法区主要存储 被虚拟机加载的 类的信息,常量,静态变量,即时编译器编译后的代码等数据。

    • 从方法区存储的数据我们可以读出下面的一些内容:
    1. 常量(final),静态变量(static)时保存到 方法区里面的。
    2. 运行时常量池: 这里的常量和java 里面的定义的常量不同,java 里面声明常量 就是被final 修饰的变量。运行时常量池是指 java 代码生成或者在编译期间 生成的 字面量(如字符串”abc“,1,这些是字面量),以及引用符号(这里的引用符号也不是java 里面的引用,而是一些底层指令符号)。

    这里我们至少知道了在编写一个java 对象时 我们的 常量(final),静态变量(static)在jvm 运行时区所在的位置。

    java 里面的变量:成员变量,局部变量(方法参数或者方法内部的变量),常量,静态变量。我们知道了后面两种的存放位置,那么 成员变量和局部变量又存放到哪里的呢?下面我们来讲讲成员变量存放的位置。

    • (线程共享区域)

    堆内存是java 对象主要的存放位置以及数据引用存放的位置,也是垃圾回收期主要工作的内存区域。我们new 的对象 就是存放在这里的。

    我们知道 类对成员变量声明周期时和类对象一样的,所以成员变量存放的位置也是在堆内存里面。下面我们就来说说局部变量的位置。

    • jvm 栈(线程私有的)

    jvm 栈是表述在java 方法执行时的数据状态,方法的调用就在jvm 栈中进行的。
    虚拟机栈描述的是Java方法执行的内存模型:每个方法在执行的同时都会创建一个栈帧用于储存 局部变量表、操作数栈、动态链接、方法出口等信息。
    每个方法从调用直至完成的过程,就对应着一个栈帧在虚拟机栈中入栈到出栈的过程。栈内存就是虚拟机栈,或者说是虚拟机栈中局部变量表的部分
    局部变量表存放了编辑期可知的各种基本数据类型(boolean、byte、char、short、int、float、long、double)、对象引用(refrence)类型和returnAddress类型(指向了一条字节码指令的地址)
      其中64位长度的long和double类型的数据会占用两个局部变量空间,其余的数据类型只占用1个。
      局部变量表所需的内存空间在编译器间完成分配,当进入一个方法时,这个方法需要在帧中分配多大的局部变量空间是完全确定的,在方法运行期间不会改变局部变量表的大小。

    jvm 栈主要时对java 中的方法执行过程的描述,也就说jvm 在执行一个java 方法时需要的数据,引用,方法的返回等这些数据的一个存法位置。jvm 栈的基本单元栈帧 里面的数据我会在后面结合 java 代码说明。

    目前为止 我们知道了 jvm 运行时数据区的3个区域,以及我们java 代码中的变量 存放的位置和 jvm 在执行java 方法时的所需数据的存放位置。下面我们来说一下程序计数器和本地方法栈。

    • 本地方法栈 (线程私有区域)

    本地方法栈和虚拟机栈发挥的作用是非常类似的,他们的区别是虚拟机栈为虚拟机执行Java方法(也就是字节码)服务,而本地方法栈则为虚拟机使用到的Native方法服务

    • 程序计数器(线程私有区域)

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

    • 私有线程区域和共享区域

    jvm 将5个区域分为 线程私有区域和共享区域。私有区域:程序计数器,jvm 栈,本地方法栈。共享区域:堆,方法区。
    从这个分类以及各个变量存放的位置以及jmm 内存模型,可以看出多线存在安全性问题的根本原因。因为多线程如果去操作共享资源(一般都是成员变量)这块内存是线程共享的,再结合jmm 模型,多线程的复合(读,写)操作一定会产生线程安全问题。

    相关文章

      网友评论

        本文标题:jvm 运行时数据区-01

        本文链接:https://www.haomeiwen.com/subject/vgfqsctx.html