JVM作为java真正的底层部分,其涉及的技术不管是在面试中,还是日常排查bug以及优化代码方面都非常重要。
JVM
实际的工作是将编译的 class 代码(字节码)翻译成底层操作系统可以运行的机器码并且进行调用执行。
类加载
类的生命周期会经历七个阶段:加载、连接(验证、准备、解析)初始化、使用、卸载。
-
加载:参考
java.lang.ClassLoader
的loadClass()
方法,JVM要做三件事:通过一个类的全限定名来获取其二进制字节流
;将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构
;在java堆中生成一个代表这个类的java.lang.Class对象
,作为方法区这些数据的访问入口。最后的结果是堆中有该类的Class对象,方法区中有该类的属性和方法。 -
验证:为了确保Class文件的字节流中包含的信息符合当前虚拟机的要求,包括文件格式校验,元数据验证等,该过程不是必须的。
-
准备:为类变量分配内存并设置类变量初始值,这些内存都将在方法区中进行分配,这时候进行内存分配的仅包括类变量(static 修饰的变量),1.8之后类变量随着类对象一起存放到堆中,实例变量将会在对象实例化时随着对象一起分配在java堆中。
-
解析:解析阶段是虚拟机常量池内的符号引用替换为直接引用的过程。比如调用方法run(),run()就是符号引用,其物理内存地址就是直接引用。
-
初始化:初始化阶段是对类变量初始化,执行类构造器
()方法的过程。
垃圾回收
HotSpot中使用的垃圾收集器主要包括 7 个:Serial
、ParNew
、Parallel Scavenge
、Serial Old
、Parallel Old
、CMS
和 G1
(Garbage First)收集器。
垃圾回收器
Serial
是单线程运行的垃圾收集器,其单线程是指在进行垃圾回收时所有的工作线程必须暂停,直到垃圾回收结束为止。ParNew
收集器实际上是 Serial 收集器的多线程并行版本。Parallel Scavenge
也是一个并行运行的垃圾回收器;不同的是,该收集器关注的侧重点是实现一个可以控制的吞吐量。Serial Old
收集器为 Serial 收集器的老年代版本,而Parallel Old
收集器是 Parallel Scavenge 收集器的老年代版本。CMS
收集器强调的是提供最短的停顿时间,它主要应用在 Java Web 项目中,它满足了系统需要短时间停顿的要求,以此来提高用户的交互体验。G1
收集器将内存划分为多个 Region 分区,这样它就可以用相对较少的时间优先回收包含垃圾最多区块。从 JDK 9 之后也成了官方默认的垃圾收集器。- 新生代垃圾收集器有:Serial、ParNew、Parallel Scavenge,老生代的垃圾收集器有:Serial Old、Parallel Old、CMS,而 G1 属于混合型的垃圾收集器。