java 虚拟机原理,
java 虚拟机原理,
什么是JVM
JVM是Java Virtual Machine(Java虚拟机)的缩写,是一个虚构出来的计算机,它屏蔽了与具体操作系统平台相关的信息,使得Java程序只需生成在Java虚拟机上运行的目标代码(字节码,ByteCode), 就可以在多种平台上不加修改地运行。这背后其实就是JVM把字节码翻译成具体平台上的机器指令,从而实现“一次编写,到处运行(Write Once, Run Anywhere)”。
Java为什么能够跨平台?
Java引入了字节码的概念,jvm 只能认识字节码,并将它们解释到系统的API调用。针对不同的系统有不同的jvm实现,有 Linux 版本的 jvm 实现,也有 Windows 版本的 jvm 实现,但是同一段代码在编译后的字节码是一样的。在不同的系统平台上运行是通过JAVA解释器将字节码解释为不同平台的机器码,在不同的 jvm 实现上会映射到不同系统的 API 调用,从而实现代码的不加修改即可跨平台运行。
JVM、JRE、JDK的关系
三者的关系是:JDK>JRE>JVM
java虚拟机运行原理
按照阶段分为两个阶段:
编译阶段:当我们将一个.java的文件进行编译,编译程序会生成一个相同名字而后缀为.class的文件。
运行阶段主要分为以下步骤:
JVM内存分区
本地方法栈
本地方法栈和java虚拟机栈功能类似,本地方法栈主要管理本地方法栈的调用,一般是指有C实现的。和java虚拟机栈一样会抛出StackOverFlowError和OutOfMemoryError异常
方法区
方法区是java内存区域中比较重要的一部分,主要保存的信息是元数据。其中最为重要的是类的类型信息、常量池、域信息、方法信息。
Java堆
Java堆可以说是Java运行时内存中最为重要的一部分,几乎所有的对象和数据都是在堆中分配空间的。Java堆分为新生代和老年代两个部分,新生代用于存放刚刚产生的对象,如果对象一直没有被回收,生存的足够长,老年对象就会被移入老年代。
新生代又可以细分为eden、surivor space0(s0或者from space)和surivor space1(s1或者To space)。eden存放刚刚创建的对象,s0和s1存放的对象至少经历了一次垃圾回收,等幸存下来。如果幸存去的对象到了指定年龄仍未被回收,就会进入老年代。
持久代:Permanent Generation。在Sun的JVM中就是方法区的意思,尽管有些JVM大多没有这一代。主要存放常量及类的一些信息默认最小值为16MB,最大值为64MB
垃圾收集算法
- Mark-Sweep(标记-清除)算法
分为“标记”和“清除”两个阶段:首先标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象。
- 缺点:空间问题,标记清除之后会产生大量不连续的内存碎片,空间碎片太多可能会导致以后在程序运行过程中需要分配较大对象时,无法找到足够的连续内存而不得不提前触发另一次垃圾收集动作;
- 优点:简单快速
- Copying(复制)算法
它将可用内存按容量划分为大小相等的两块,每次只使用其中的一块。当这一块的内存用完了,就将还存活着的对象复制到另外一块上面,然后再把已使用过的内存空间一次清理掉。- 缺点:内存使用率只有一半
- 优点:不会产生碎片
Mark-Compact(标记-整理)算法
标记过程仍然与“标记-清除”算法一样,但后续步骤不是直接对可回收对象进行清理,而是让所有存活的对象都向一端移动,然后直接清理掉端边界以外的内存,
分代收集算法
当前商业虚拟机的垃圾收集都采用“分代收集”(Generational Collection)算法,根据对象存活周期的不同将内存划分为几块并采用不用的垃圾收集算法。
一般是把 Java 堆分为新生代和老年代,这样就可以根据各个年代的特点采用最适当的收集算法。在新生代中,每次垃圾收集时都发现有大批对象死去,只有少量存活,那就选用复制算法,只需要付出少量存活对象的复制成本就可以完成收集。而老年代中因为对象存活率高、没有额外空间对它进行分配担保,就必须使用“标记—清理”或者“标记—整理”算法来进行回收。
垃圾收集器
- Serial收集器
新生代收集器,使用停止复制算法,使用一个线程进行GC,串行,其它工作线程暂停。 - ParNew收集器
新生代收集器,使用停止复制算法,Serial收集器的多线程版,用多个线程进行GC,并行,其它工作线程暂停,关注缩短垃圾收集时间。 - Parallel Scavenge 收集器
新生代收集器,使用停止复制算法,关注CPU吞吐量,即运行用户代码的时间/总时间,比如:JVM运行100分钟,其中运行用户代码99分钟,垃 圾收集1分钟,则吞吐量是99%,这种收集器能最高效率的利用CPU,适合运行后台运算(关注缩短垃圾收集时间的收集器,如CMS,等待时间很少,所以适 合用户交互,提高用户体验)。 Serial Old收集器
老年代收集器,单线程收集器,串行,使用标记整理(整理的方法是Sweep(清理)和Compact(压缩),清理是将废弃的对象干掉,只留幸存的对象,压缩是将移动对象,将空间填满保证内存分为2块,一块全是对象,一块空闲)算法,使用单线程进行GC,其它工作线程暂停(注意,在老年代中进行标记整理算法清理,也需要暂停其它线程),在JDK1.5之前,Serial Old收集器与ParallelScavenge搭配使用。
- Parallel Old收集器
老年代收集器,多线程,并行,多线程机制与Parallel Scavenge差不错,使用标记整理(与Serial Old不同,这里的整理是Summary(汇总)和Compact(压缩),汇总的意思就是将幸存的对象复制到预先准备好的区域,而不是像Sweep(清理)那样清理废弃的对象)算法,在Parallel Old执行时,仍然需要暂停其它线程。Parallel Old在多核计算中很有用。Parallel Old出现后(JDK 1.6),与Parallel Scavenge配合有很好的效果,充分体现Parallel Scavenge收集器吞吐量优先的效果。 cms(concurrent mark sweep)收集器
老年代收集器,致力于获取最短回收停顿时间(即缩短垃圾回收的时间),使用标记清除算法,多线程,优点是并发收集(用户线程可以和GC线程同时工作),停顿小。使用-XX:+UseConcMarkSweepGC进行ParNew+CMS+Serial Old进行内存回收,优先使用ParNew+CMS(原因见后面),当用户线程内存不足时,采用备用方案Serial Old收集。- G1收集器
相关文章
- 暂无相关文章
用户点评