主页 > IT > JVM小结

JVM小结

归类于 IT

JVM即Java虚拟机,是提供Java程序运行功能的“机器”。JVM通过虚拟真实的计算机功能,提供了Java程序运行的环境,使得Java程序实现跨平台特性。JVM包括一套字节码指令集,一组寄存器,一个栈,一个垃圾回收堆和一个存储方法域。

JVM的体系结构包括:类装载器(class loader)和执行引擎(execution engine)两个子系统以及运行时数据区(runtime data area)和本地接口(native interface)两个组件。
jvm1
1) 类装载器
类装载器根据给定的全限定类名,装载类文件到运行时数据区。

2) 执行引擎
执行类文件中的指令。每个运行的线程都有一个Execution engine实例。

3) 运行时数据区
这个组件就是JVM中的内存,包括方法区,堆,栈,程序计数器,本地方法栈五个部分。堆和方法区被所有线程共享,而栈,程序计数器和本地方法栈是线程私有的,即每个线程都会具有自己的栈,程序计数器和本地方法栈。

1. 堆
一个JVM实例只有一个堆空间,保存Java程序运行时创建的所有类实例或数组,被所有线程共享,因此需要考虑多线程情况下对象的同步问题。堆可能出现的异常为:java.lang.OutOfMemoryError: Java heap space

2. 方法区
被装载的类文件内容被类装载器读取后,JVM提取其中的信息并保存在方法区中。类中的静态变量也存储在方法区中。方法区也是线程共享的,需要考虑同步问题。方法区可能出现的异常:java.lang.OutOfMemoryError: PermGen full

3. 栈
Java栈以帧为单位保存线程的运行状态。虚拟机只会直接对Java stack执行两种操作:以帧为单位的压栈或出栈。每当线程调用一个方法的时候,就对当前状态作为一个帧保存到java stack中(压栈);当一个方法调用返回时,从java stack弹出一个帧(出栈)。栈的大小是有一定的限制,这里可能出现StackOverflow异常。

4. 程序计数器
每个运行中的Java程序,每一个线程都有它自己的PC寄存器,也是该线程启动时创建的。PC寄存器的内容总是指向下一条将被执行指令的地址。

5. 本地方法栈
对于一个运行中的Java程序而言,它还能会用到一些跟本地方法相关的数据区。当某个线程调用一个本地方法时,它就进入了一个全新的并且不再受虚拟机限制的世界。本地方法可以通过本地方法接口来访问虚拟机的运行时数据区,不止与此,它还可以做任何它想做的事情。比如,可以调用寄存器,或在操作系统中分配内存等。总之,本地方法具有和JVM相同的能力和权限。这里可能出现JVM无法控制的内存溢出问题native heap OutOfMemory

4) 本地接口
与native libraries交互,是其它编程语言交互的接口。

JVM一个很重要的功能是垃圾回收(Garbage Collection)。SUN JVM实现基于对对象生命周期分析后得出的垃圾回收算法,即分代垃圾回收机制。把对象分为年轻代、年老代、持久代,对不同生命周期的对象使用不同的算法(上述方式中的一个)进行回收。
jvm2
1) 年轻代
分为三个区,一个Eden区和两个Survivor区。大多数对象在Eden区中生成。如果Eden区已满,还存活的对象将被复制到Survivor区(二选一)。如果一个Survivor区满了,则将存活对象复制到另一个Survivor区,如果这一个个Survivor也满了,则从第一个Survivor区复制的仍存活的对象将被复制到年老区。Survivor同一个区中可能同时存在从Eden复制过来的对象,和从前一个Survivor区复制过来的对象,而复制到年老区的只有从第一个Survivor复制过来的对象。而且,Survivor区总有一个是空的。

2) 年老代
年老代存放从年轻代存活的对象。年老代存放的对象一般来说生命期较长。

3) 持久代
用于存放静态文件,如Java类、方法等。持久代对垃圾回收没有显著影响,但是有些应用可能动态生成或者调用一些class,例如Hibernate等,在这种时候需要设置一个比较大的持久代空间来存放这些运行过程中新增的类。

Java的四个核心:Java程序语言,JVM,Java class文件及Java API。

Java虚拟机中,数据分为基本类型和引用类型(由于包含基本类型,而基本类型不是类,所以Java并非完全面向对象),基本类型变量保存本身的值,而引用类型变量保存的是对象的引用,实际保存的是对象所在的地址。
基本类型包括:boolean,byte,char,short,int,long,float,double和returnAddress;
引用类型包括:类类型,接口类型和数组;

对比分析:如果把Java原程序想象成我们的C++原程序,Java原程序编译后生成的字节码就相当于C++原程序编译后的80×86的机器码(二进制程序文件),JVM虚拟机相当于80×86计算机系统,Java解释器相当于80x86CPU。在80x86CPU上运行的是机器码,在Java解释器上运行的是Java字节码。Java解释器相当于运行Java字节码的“CPU”,但该“CPU”不是通过硬件实现的,而是用软件实现的。Java解释器实际上就是特定的平台下的一个应用程序。只要实现了特定平台下的解释器程序,Java字节码就能通过解释器程序在该平台下运行,这是Java跨平台的根本。当前,并不是在所有的平台下都有相应Java解释器程序,这也是Java并不能在所有的平台下都能运行的原因,它只能在已实现了Java解释器程序的平台下运行。

归类于 IT

评论已经关闭

顶部