Java编写的程序通过Java编译器编译成Java字节码(class文件),Java虚拟机载入字节码, 解释运行程序。
Java虚拟机(Java Virtual Machine 简称JVM) 是运行所有Java程序的抽象计算机,是Java语言的运行环境。 Java虚拟机有自己完善的硬体架构,如处理器、堆栈、寄存器等,还具有相应的指令系统。 JVM屏蔽了与具体操作系统平台相关的信息,使得Java程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。
是Java运行时环境(Java Runtime Environment)的一部分,负责动态加载Java类到Java虚拟机的内存空间中。(1) 装载:查找和导入Class文件;(2) 链接:把类的二进制数据合并到JRE中;
(3) 初始化:对类的静态变量,静态代码块执行初始化操作 (4) 使用: 类的使用 (5) 卸载: 生命周期结束
负责执行class文件中包含的字节码指令
主要是调用C或C++实现的本地方法及返回结果
垃圾回收主要有两个步骤:
以根集对象为起始点进行搜索,如果有对象不可达的话,即是垃圾对象。这里的根集一般包括java栈中引用的对象、方法区常良池中引用的对象,本地方法中引用的对象等。
此算法执行分两阶段。第一阶段从引用根节点开始标记所有被引用的对象,第二阶段遍历整个堆,把未标记的对象清除。此算法需要暂停整个应用,同时,会产生内存碎片。
标记整理算法类似与标记清除算法,不过它标记完对象后,不是直接对可回收对象进行清理,而是让所有存活的对象都向一端移动,然后直接清理掉边界以外的内存。
此算法把内存空间划为两个相等的区域,每次只使用其中一个区域。 垃圾回收时,遍历当前使用区域,把正在使用中的对象复制到另外一个区域中。 此算法每次只处理正在使用中的对象,因此复制成本比较小,同时复制过去以后还能进行相应的内存整理,不会出现“碎片”问题。当然,此算法的缺点也是很明显的,就是需要两倍内存空间
上述讲解如何区分垃圾,以及垃圾是如何回收的, 现在我们来看看HotSpot JVM是如何实现垃圾回收的。
如果说垃圾收集算法是方法论, 那么垃圾收集器就是内存回收的具体实现。
垃圾收集器 | 适用区 | 类别 | 算法 | 使用场景 |
---|---|---|---|---|
Serial | 新生代 | 串行 | 复制算法 | 单CPU环境下的Client模式 |
ParNew | 新生代 | 并行 | 复制算法 | 多CPU环境时在Server模式下与CMS配合 |
Parallell Scavenge | 新生代 | 并行 | 复制算法 | 在后台运算而不需要太多交互的任务 |
CMS | 老年代 | 并发 | 标记-清除算法 | 集中在互联网站或B/S系统服务端上的Java应用 |
Serial Old | 老年代 | 串行 | 标记-整理算法 | 单CPU环境下的Client模式、CMS的后备预案 |
Parallel Old | 老年代 | 并行 | 标记-整理算法 | 在后台运算而不需要太多交互的任务 |
G1 | 新年代与老年代 | 并行与并发 | 标记-整理算法 | 面向服务端应用,将来替换CMS |
其中:
上图展示了7种作用于不同分代的收集器,如果两个收集器之间存在连线,就说明它们可以搭配使用。 虚拟机所处的区域,则表示它是属于新生代收集器还是老年代收集器。 Hotspot实现了如此多的收集器,正是因为目前并无完美的收集器出现,只是选择对具体应用最适合的收集器
本片文章比较简单介绍了Java虚拟机, 相信对大家对Java虚拟机有了一定的了解。 当然文中很多方面都没进行深入讲解,如果想更深刻的了解原理可以自行购买相关书籍或者网上搜索相关内容进行学习。 推荐学习书籍《深入理解Java虚拟机-JVM高级特性与最佳实践》
参考资料:
喜欢可以关注公众号: 终身幼稚园