JVM内部结构图及各模块运行机制总结

1 篇文章 0 订阅

1.JVM内部模型图

JVM执行流程:

利用前端编译器(javac)将.java文件编译为.class文件(字节码文件),然后通过类加载子系统将.class文件加载到运行时数据区,之后通过执行引擎对.class文件进行解释执行。

2 类加载子系统

类加载子系统有七个操作:加载、链接(验证、准备、解析)、初始化、使用、卸载

2.1 加载

把.class文件读取到运行时数据区中,详细步骤为:

(1)通过全限定名读取到该类的二进制流(即,.class文件);

(2)将该二进制流的静态结构读取到运行时数据区中的方法区中;

(3)在堆中创建该类的实例对象。

注意:加载时采用的是双亲委派机制,其原理如下图所示,当某个类加载器收到类加载请求时,会自底向上将此请求委派给其父类加载器,若最顶层的启动类加载器(Bootstrap ClassLoader)不能加载此类,则自上而下把请求交还给其子类加载器,途中有类加载器可以加载此类,则进行加载,否则一直往下传递。若到达最底层的自定义类加载器(若没有自定义类加载器,则就是应用程序类加载器(Application ClassLoader))仍无法加载此类,则报出异常。

2.2 链接

2.2.1 验证

验证字节码文件是否符合JVM规范,比如字节码文件的文件开头是“CA FE BA BE”(称为魔数),这标识了它是JVM的字节码文件。

2.2.2 准备

为静态变量(static修饰)分配内存并赋初始值。

2.2.3 解析

将常量池中的符号引用(如#1,#2可能代表某个类,某个方法的符号引用)变为直接引用(内存地址)。

2.3 初始化

将静态变量的赋值动作以及静态代码块(static{})发生的操作整合为clinit方法进行执行。其实就是为静态变量进行真正意义上的赋值。

2.4 使用

2.5 卸载

3 运行时数据区

3.1线程私有区域

Java虚拟机栈:

保存局部变量表操作数栈动态链接方法出口;每个线程单独拥有一个,用于执行程序;栈中的以栈帧为一个单位,一个栈帧相当于一个方法;执行流程:当调用main方法时,会将main方法作为一个栈帧压入到栈顶,若在执行main方法时调用了其它方法,则会把其它方法也作为栈帧压入栈顶,当栈顶方法执行完毕就会弹出栈。若所有栈帧都弹出,则程序运行结束。

本地方法栈:

本地方法栈与Java虚拟机栈类似,但它是为了执行本地方法(Native Methods)。本地方法栈执行时,需要调用到本地方法接口(也叫JNI/Java Native Interface),而本地方法接口需要调用本地方法库。

程序计数器:

控制程序指令的执行顺序,程序该怎么执行,哪个方法先执行,哪个方法后执行。

3.2 线程共享区域

方法区:

保存类的信息、常量池、方法数据、方法代码、JIT代码缓存等等;方法区是一种逻辑上的概念(即,JVM规范),在JDK1.7及之前方法区的落地实现叫做永久代(PermGen space),它位于堆中。在JDK1.8永久代被移除,将其变为元空间(Metaspace)。元空间与永久代最大区别在于,元空间使用的是直接内存(本地内存),而永久代使用的是堆内存。

Java堆:

保存new出来的实例对象

JDK1.6时字符串常量池在运行时常量池内,属于运行时常量池的一部分;

JDK1.6到JDK1.7的变化是把静态常量和字符串常量从方法区中移到了堆中;

JDK1.7到JDK1.8的变化是对方法区的实现由永久代变为了元空间。

即字符串常量池在JDK1.7之后就移到了堆中,且存储的是字符串对象的引用,而不是对象本身。

在JDK1.8版本中,Java堆划分为新生代(NewGen)和老生代(OldGen)。

新生代:

  1. 新生代由伊甸区(Eden space)、幸存from区(Survival from)、幸存to区(Survival to)构成。
  2. 新生代发生的GC是轻GC(Minor GC),使用的GC算法是复制算法,复制算法原理是:当触发Minor GC时,利用可达性分析算法将Eden区存活对象移到Survival to区域,同时也将Survival from区域的存活对象也移到Survival to区域,然后将Survival to区域存活对象都复制到Survival from区域,且清除那些失效对象。即,每次GC都是将存活对象存入到Survival to区域,然后将Survival from区域和Survival to区域调换位置(实际是对象的复制过程)来保证Survival to区域是空的。
  3. 复制算法适合存活周期较短的对象的垃圾回收,其优点是算法复杂度低,执行效率快,但内存空间浪费较大。

老生代:

  1. 老生代发生的是重GC(Full GC),使用的是标记清除标记整理算法的混合版,当内存碎片产生较少时,使用标记清除算法。较多时,使用标记整理算法。
  2. 标记清楚算法:利用可达性分析算法标记存活对象(可达对象),然后统一删除不可达对象。共两次操作,执行效率较低,且可能会产生较多内存碎片,相比复制算法,内存浪费较少。
  3. 标记整理算法:利用可达性分析算法标记存活对象(可达对象),然后将它们移至一端,删除端以外的不可达对象。这样就可用保证内存的连续性,不会有内存碎片,内存使用率大幅提高,但是执行效率更低。

4 执行引擎

执行引擎由解释器、JIT编译器、垃圾回收器组成。

解释器:

用于程序代码的解释执行。

JIT编译器:

用于将热点代码(重复执行次数较多的代码)提前编译,存储在方法区中,以便下次使用。这是为了程序执行的效率考虑。

垃圾回收器:

新生代垃圾回收器:Serial、ParNew、Parallel Scavenge

老生代垃圾回收器:Serial Old、Parallel Old、CMS

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值