JVM整体结构
-
堆 线程共享的区域,也是垃圾回收器要收集的区域,这地方主要保存用户创建的对象。例如 new User(),这个对象是保存在堆上面的。
-
栈 栈上面用来保存方法运行产生的局部变量、方法返回值和动态链接。
-
本对方法栈 是用来保存本地方法(native)执行的栈结构
-
方法区 在jdk1.8中已经更名为元空间了,这里面主要保存如下内容:
-
类型信息
- 类型的全限定名
- 超类的全限定名
- 直接超接口的全限定名
- 类型标志(该类是类类型还是接口类型)
- 类的访问描述符(public、private、default、abstract、final、static)
-
类型的常量池
-
字段信息
- 字段修饰符(public、protect、private、default)
- 字段的类型
- 字段名称
-
方法信息
-
类变量
-
各种引用
- 类实例的引用
- 加载器的引用
-
方法表 方法表是以非抽象类为纬度创建的数组,数组里面的元素是类中每个方法的直接引用,提升访问效率。
-
-
程序计数器 程序计数器是用来保存所在线程在切换前执行指令所在的行号,这个主要是解决多线程情况下,进行线程切换带来的问题,如果只有单线程,其实是不需要程序计数器的。
堆区域是如何进行划分的?
了接jvm的同学应该都知道,堆其实是分为新老年代的,这主要是为了进行垃圾回收而设计的一种结构
新老年代相关jvm参数
- -XX:NewRatio 设置新老年代比例,如-XX:NewRatio=5 代表 新老年代比例为1:5,新生代占用堆内存的1/6,老年代占用5/6;jvm默认新老年代为1:2;需要注意的是如果程序启动指定了-XX:MaxNewSize值,那么设置比例的参数就会失效,老年代的值则为堆内存大小减去MaxNewSize;
- -XX:SurvivorRatio 设置新生代中eden和两个2个Survivo区域大小的比例,如-XX:SurvivorRatio=8,则eden:s1:s2=8:1:1,默认比例就是为8:1:1.
young GC发生在新生代中,FUll GC 发生在整个堆空间中,一般是老年代空间不够用就会出发FULL GC
逃逸分析
逃逸分析 主要用来分析方法内部的哪些对象是可以在在栈里面分配的,因为一般对象都是在堆中分配的,在堆中分配的对象,需要等待垃圾回收器进行回收,在回收之前会一直占用堆空间的,但是如果在一个方法内部,一个对象如果满足以下条件,是可以在栈中进行分配的:
- 是局部变量
- 没有将赋值给成员变量
- 没有被当作返回值跳出去
在jdk1.7之前需要使用-XX:+DoEscapeAnalysis参数进行开启,jdk1.7默认开启逃逸分析,如果需要关闭也是使用-XX:+DoEscapeAnalysis 参数进行关闭
什么是即时编译技术
我们写说下JVM的运行模式有哪几种?
-
解释模式 执行一行字节码就编译成一行机器码执行
- 特点:使用解释模式,JVM启动速度快,但是执行执行命令慢,需要一行一行进行编译
-
编译模式 先将所有字节码全部编译为机器码,然后一次性加载所有机器码执行
- 特点:使用编译模式,JVM启动速度会稍微慢点,因为需要进行编译,但是执行的时候几乎不需要有任何消耗
-
混合模式 使用解释模式执行代码,但是如果碰到一些热点或共用的代码片段,会采用编译模式执行,并且会将编译的内容缓存起来,减少重复编译,从而提高代码执行效率,这个也是JVM默认采用的编译模式,这个就是JIT(即时编译技术)
微信搜一搜【乐哉开讲】关注帅气的我,回复【干货领取】,将会有大量面试资料和架构师必看书籍等你挑选,包括java基础、java并发、微服务、中间件等更多资料等你来取哦。