深入理解JVM-- JAVA内存模型、对象的访问模式(一)

深入理解JVM-- JAVA内存模型、对象的访问模式

一、JAVA内存模型

​ 开发离不开内存的支持,所以在开发者使用Java进行程序开发的过程之中,如果要想实现程序的高效运行效果,那么必须对整个Java的内存体系有所掌握。而如果要想理解整个Java的内存体系,那么首先必须清楚Java程序的执行流程。

深入理解JVM-- JAVA内存模型、对象的访问模式(一)

java内存模型

程序的执行步骤:

  1. 按照功能的要求编写一个*.java的源程序,而后要利用Java提供的编译器(javac.exe)将*.java的源程序编译为JVM可以使用的*.class字节码文件;

  2. 当进行Java程序类解析时(使用java.exe启动JVM进程),JVM会通过类加载器(可以使用系统默认的类加载器,也可以采用自定义类加载器)加载各个类的字节码文件,随后会将操作继续交由JVM执行引擎处理;

  3. 如果在一个程序中需要调用本地的C程序函数库,则可以通过本地方法接口实现与函数库进行连接

  4. 在整个程序执行过程之中,JVM会使用一段空间来存储程序执行期间所需要用到的数据和相关信息,而这段空间就被称为运行时数据区,即:JVM内存。

    深入理解JVM-- JAVA内存模型、对象的访问模式(一)

    堆内存: 保存所有引用数据类型的真实信息。堆内存主要保存具体的数据信息,在JVM启动时将被自动创建。此内存空间为所有线程对象共享区域,但是在Java开发之中,开发人员可以不用去处理此区域的空间释放,会由Java垃圾收集器自动进行释放,所以此空间为垃圾收集器的主要管理区域。

    栈内存: 基本类型、运算、指向堆内存的指针。又被称为“Java虚拟机栈”(Java Vitual Machine Stack)每个线程都会存在私有的栈内存空间。在线程对象每一次调用一个方法时都会自动产生一个栈帧,并且将这些栈帧保存在该栈之中,并遵循“后进先出”的原则

    深入理解JVM-- JAVA内存模型、对象的访问模式(一)

    方法区: 方法区是整个JVM中非常重要的一块内存区,此块区域是所有线程对象共享的区域。在方法区中保存了每一个类的信息(类名称、方法信息、成员信息、接口信息等)、静态变量、常量、常量池信息。一般而言在方法区中很少会去执行垃圾收集操作。

    程序计数器: 在编译时会为每一个字节码文件中的程序代码分配一个程序位置,用于标注下一个要执行的指令位置。对于程序计数器可以简单理解为是一个行号的指示器,这样Java解释器在执行字节码文件的时候,会依据行号的顺序一直向下执行。每一个线程都有一个自己独立的程序计数器,只会记录该线程执行顺序,所以它属于线程私有区域。并且该区域所占用的内存空间极其小(小到几乎可以忽略)。

    本地方法栈: 本地方法栈的功能与Java栈内存的功能类似,唯一的区别在于本地方法栈是为本地方法(Native Method)服务的。

​ 补充:栈帧组成

本地变量表(Local Variables) :方法的局部变量或形参,其以变量槽(solt)为最小单位,只允许保存32位长度的变量,如果超过32位则会开辟两个连续的solt(64位长度,long和double)

操作数栈(Operand Stack):由于表达式计算都在栈中完成,所以会专门提供一块数据空间供方法计算使用;

指向当前方法所属的类的运行时常量池的引用(Reference to runtime constant pool): 引用其它类的常量或者使用String池中的字符串;

​ **方法返回地址(Return Address):**方法执行完后需要返回调用此方法的位置,所以需要在栈帧中保存方法返回地址

​ 注意:在整个Java中存在有对象池的概念,对象池中的常量在jvm启动初始化的时候已经分配好内存空间了,但是string中的intern()方法可以打破这种限制,动态分配常量池的内存。

​ 对于运行时的数据区直接和Java中的线程对象有关联,所谓的Java调优调整的都是运行时的数据区,在整个过程中,我们操作的主要是堆内存(共享的地方)。

二、对象的访问模式

​ Java中的引用类型是最为重要的数据处理模型,整个的引用数据类型的处理中会牵扯到,堆、栈、方法区。

Object obj = new Object()
  • Object obj 描述的保存在栈内存之中,保存有堆内存的引用,这个数据会保存在本地变量表中;
  • new Object() 一个实例化对象,该数据将保存在堆内存之中;

深入理解JVM-- JAVA内存模型、对象的访问模式(一)

​ 实际上存在着三种虚拟机:HotSpot、JRockit、JVM’s,自从Oracle受够了sun公司和BEA公司之后在将前面两种混合为一种。

深入理解JVM-- JAVA内存模型、对象的访问模式(一)

​ 混合模式指的是适合编译和执行。但是有时候我们并不需要执行,可以使用纯解释模式启动。

深入理解JVM-- JAVA内存模型、对象的访问模式(一)

使用纯编译模式启动:

深入理解JVM-- JAVA内存模型、对象的访问模式(一)

​ 实际上Java的设计都开始在为服务器而准备的。

  • “-server”:服务器模式,占用的内存大、启动速度慢(默认)
  • “-client”:启动的速度快。