JVM 垃圾回收原理 - 1、JVM执行分析

一、Java内存模型

   所有的Java程序代码必须保存在*.java的文件之中,这些称为源代码,而这些源代码并不能够直接执行,
必须使用javac.exe命令将其编译为.class文件,而后利用java.exe命令在JVM进程之中解释此程序。

【 Java程序执行流程 】


      实际上当JVM将所需要的*.class文件加载到JVM进程之中,那么这个过程就需要有一个类加载器(ClassLoader),
有了类加载器的好处在于:可以随意指定程序*.class文件的所在路径。
      JVM:Java虚拟机,所有的程序都要求运行在JVM上,是因为考虑到了可    ,可是如果要想真正去执行程序,
你绝对不可能离开操作系统的支持。

     在Java里面可以使用native实现本地C函数的调用,但是这些都属于     ,而真正的程序运行都在”运行时数据区”之中。


在整个的运行时数据区之中,分为如下几块内存空间:
• 堆内存:保留所有引用数据类型的真实信息;
• 栈内存:基本类型、运算、指向堆内存的指针;
• 方法区:所有定义的方法的信息都保存在方法区之中,此区属于共享区;
• 程序计数器:是一个非常小的内存空间,小的可以忽略;
• 本地方法栈:每一次执行递归的方法处理的时候实际上都会将上一个方法入栈。  ???


【 Java虚拟机栈--------栈桢(Stack Frame) 】
➤Java虚拟机栈会存放的是多个栈桢,包括如下主要成员部分:
   ➢ 局部变量表(Local Variables):方法的局部变量或形参,其以变量槽(solt)为最小单位,只允许保存32位长度的变量,
       如果超过32位则会开辟两个连续的solt(64位长度,long和double);
  ➢ 操作数栈(Operand Stack):表达式计算在栈中完成;
  ➢ 指向当前方法所属的类的运行时常亮池的引用(Reference to runtime constant pool):引用其它类
      的常量或者使用String池中的字符串;
  ➢ 方法返回地址(Return Address):方法执行完后需要返回调用此方法的位置,所以需要在栈桢中保存

      方法返回地址;

【 Java虚拟机栈 ------ 栈帧(Stack Frame)】


     在整个Java之中存在有对象池的概念,对象池是对整个常亮池的一个规则破坏,因为在JVM启动的时候所有的常量都已经分配好内存空间了,但是String中的intern()方法却可以打破这种限制,动态的进行常量池的内容设置。

【 Java内存管理 ------- 总结 】


➤ JVM中的运行时数据区包括:
   ➣ 程序计数器(Program Counter Register)
   ➣ Java栈(Stack)
   ➣ 本地方法栈(Native Method Stack)
   ➣ 方法区(Method Area)
   ➣ 堆(Heap)
➤ 栈是运行时的单位,而堆是存储的单元。
  ➣ 栈因为是运行单位,里面存储的信息都是跟当前线程(或程序)相关的信息。
     包括局部变量、程序运行状态、方法返回值等等;

  ➣ 堆只是保存对象信息。

二、Java对象访问模型

     Java的引用类型是最为重要的数据处理模型,而整个的引用数据类型数据处理之中会牵扯到:堆内存、栈内存、方法区。
所以下面以一个最简单的程序代码为主:”Object obj = new Object()”,实例化了一个Object类对象:
   • “Object obj”:描述的是保存在栈内存之中,而保存有堆内存的引用,这个数据会保存在本地变量表中;
   • “new Object”:一个真正的对象,对象保存在堆内存之中。
直观的思路整个引用的操作:
    • 新定义的对象的名称保存在本地变量表,而后在这块区域里需要确定要与之对应的栈内存空间;
    • 通过变量表中的栈地址可以找到堆内存;
    • 利用堆内存的对象进行本地方法的调用(方法区)。

【 通过句柄访问 】


【 通过直接指针访问-------HotSpot虚拟机 】


    但是在Java之中它直接利用的是对象保存模式,也就是说堆内存里面不再需要保存句柄,而直接保存具体的对象,
就相当于省略了句柄到对象间的查找,而后这个对象可以直接进行Java方法区的调用。
    在实际上有三中JVM:
         • SUN公司最早改良的HotSpot ;
         • BEA公司的:JRockit ;
         • IBM JVM’s ;
    而Oracle在收购了SUN与BEA两家公司之后得到了业内的两个虚拟机的版本。

范例:取得当前的JVM版本(java -version)

java version “1.8.0_74”
Java(TM) SE Runtime Environment (build 1.8.0_74-b02)

Java HotSpot(TM) 64-Bit Server VM (build 25.74-b02, mixed mode)

   所谓的混合模式指的就是适合于编译和执行。

范例:使用纯解释模式启动(java-Xint-version)
java version “1.8.0_74”
Java(TM) SE Runtime Environment (build 1.8.0_74-b02)
Java HotSpot(TM) 64-Bit Server VM (build 25.74-b02, interpreted mode)

范例:使用纯编译模式启动(java-Xcomp-version)
java version “1.8.0_74”
Java(TM) SE Runtime Environment (build 1.8.0_74-b02)
Java HotSpot(TM) 64-Bit Server VM (build 25.74-b02, compiled mode)
   实际上现在的JDK的设计都已经开始为服务器而准备的。因为对于JVM的启动有两种模式:
       • “-server”:服务器模式,占用的内存大、启动速度慢、默认模式;
       • “-client”:本地单机运行程序模式,启动的速度快。
   E:\Program Files\Java\jdk1.8.0_74\jre\lib\amd64\jvm.cfg。

【 总结 】
  引用数据类型在HotSpot中都是直接进行的引用处理,没有句柄池的概念。






猜你喜欢

转载自blog.csdn.net/androidsj/article/details/80351492