1.
2.JVM是
JVM规范
(java运行规范)的实施,VM制造者可以按照这个规范去根据自己的需求去定制化一个JVM,但无论哪一种JVM,其总体上的特征都必须满足这个java运行规范,其JVM的实现原理可以不尽相同。正如计算机的设计制造,都是根据冯诺伊曼的计算机体系研发的,但其中的实现原理可以各式各样。对cpu的构造就有很多种,如Inter,AMD,高通等等。又如c语言的编译器,可以有很多种:turborC,VC等。
3.虚拟机的安全性:
JVM的结构允许对一个Java应用进行更细微的控制。这些应用运行在沙箱(Sandbox)环境中。确保在没有恰当的许可时,无法访问到本地文件系统、处理器和网络连接。远程执行时,代码还需要进行证书认证。
4.java除了解释执行java字节码,还可以通过JIT编译器,生产可高效运行的机器码运行cpu的本地语言。
5.JVM体系结构:
JVM规范定义了一系列子系统以及它们的外部行为.
JVM的设计目标是提供一个基于抽象规格描述的计算机模型,为解释程序开发人员提很好的灵活性,同时也确保Java代码可在符合该规范的任何系统上运行。JVM对其实现的某些方面给出了具体的定义,特别是对Java
可执行代码
,即
字节码
(Bytecode)的格式给出了明确的规格。这一规格包括
操作码
和
操作数
的语法和数值、
标识符
的数值表示方式、以及Java类文件中的Java对象、
常量缓冲
池在JVM的存储映象。这些定义为JVM
解释器
开发人员提供了所需的信息和开发环境。Java的设计者希望给开发人员以随心所欲使用Java的自由。
JVM所处地位以及其内部体系结构如下图:
java 层次总览图
- JVM 栈结构
- JVM 碎片回收堆
- JVM 存储区
- bootstrap class loader:是其他类加载器的父类,它用于加载Java核心库唯一一个用本地代码编写的类加载
- extension class loader:用于加载扩展库
- system class loader:用于加载在classpath中的应用程序的类文件
- user-defined class loader:是系统类加载器或其他用户定义的类加载器的子类。
8.
执行引擎(Execution Engine)
a.解释执行:
执行引擎把它遇到的每一条指令解释为机器语言
b.即时编译: 如果一条指令经常被使用,执行引擎会把它编译为本地代码并存储在缓存中。这样,所有和这个方法相关的代码都会直接执 行,从而避免重复解释。
b.即时编译: 如果一条指令经常被使用,执行引擎会把它编译为本地代码并存储在缓存中。这样,所有和这个方法相关的代码都会直接执 行,从而避免重复解释。
JVM规范中并不规定一定要使用即时编译。即时编译也不是用于提高JVM性能的唯一的手段。规范仅仅规定了每条字节码对应的本地代码,至于执行引擎如何实现这一对应过程的,完全由JVM的具体实现来决定。
虚拟硬件结构与执行引擎子系统如图:
9.内存模型(
Memory Model
)
Java内存模型建立在自动内存管理的概念之上。当一个对象不再被一个应用所引用,垃圾回收器就会回收它,从而释放相应的内存。这一点和其他很多需要自行释放内存的语言有很大不同。
Runtime Data Area组件:这就是我们常说的JVM的内存了,
JVM是从底层操作系统中分配内存,它主要分为五个部分——
1、Heap (堆):一个Java虚拟实例中只存在一个堆空间
2、Method Area(方法区域):被装载的class的信息存储在Method area的内存中。当虚拟机装载某个类型时,它使用类装载器定位相应的class文件, 然后读入这个class文件内容并把它传输到虚拟机中。
3、Java Stack(java的栈):虚拟机只会直接对Java stack执行两种操作:以帧为单位的压栈或出栈
4、Program Counter(程序计数器):每一个线程都有它自己的PC寄存器,也是该线程启动时创建的。PC寄存器的内容总是指向下一条将被执行指令的饿地址,这里的地址可以是一个本地指针,也可以是在方法区中相对应于该方法起始指令的偏移量。
5、Native method stack(本地方法栈):保存native方法进入区域的地址
以上五部分只有Heap 和Method Area是被所有线程的共享使用的;而Java stack, Program counter 和Native method stack是以线程为粒度的,每个线程独自拥有自己的部分。
2、Method Area(方法区域):被装载的class的信息存储在Method area的内存中。当虚拟机装载某个类型时,它使用类装载器定位相应的class文件, 然后读入这个class文件内容并把它传输到虚拟机中。
3、Java Stack(java的栈):虚拟机只会直接对Java stack执行两种操作:以帧为单位的压栈或出栈
4、Program Counter(程序计数器):每一个线程都有它自己的PC寄存器,也是该线程启动时创建的。PC寄存器的内容总是指向下一条将被执行指令的饿地址,这里的地址可以是一个本地指针,也可以是在方法区中相对应于该方法起始指令的偏移量。
5、Native method stack(本地方法栈):保存native方法进入区域的地址
以上五部分只有Heap 和Method Area是被所有线程的共享使用的;而Java stack, Program counter 和Native method stack是以线程为粒度的,每个线程独自拥有自己的部分。
JVM内存模型如图:
如上图所示,为Java堆中的各代分布。
1. Young(年轻代)
年轻代分三个区。一个Eden区,两个Survivor区。大部分对象在Eden区中生成。当Eden区满时,还存活的对象将被复制到Survivor区(两个中的一个),当这个Survivor区满时,此区的存活对象将被复制到另外一个Survivor区,当这个Survivor去也满了的时候,从第一个Survivor区复制过来的并且此时还存活的对象,将被复制年老区(Tenured。需要注意,Survivor的两个区是对称的,没先后关系,所以同一个区中可能同时存在从Eden复制过来 对象,和从前一个Survivor复制过来的对象,而复制到年老区的只有从第一个Survivor去过来的对象。而且,Survivor区总有一个是空的。
2. Tenured(年老代)
年老代存放从年轻代存活的对象。一般来说年老代存放的都是生命期较长的对象。
3. Perm(持久代)
用于存放静态文件,如今Java类、方法等。持久代对垃圾回收没有显著影响,但是有些应用可能动态生成或者调用一些class,例如Hibernate等,在这种时候需要设置一个比较大的持久代空间来存放这些运行过程中新增的类。持久代大小通过-XX:MaxPermSize=进行设置。
当一个Java应用创建了一个对象,这个对象是被存储到“初生池”(
eden pool
)。一旦初生池存储满了,就会在新生代触发一次minor gc(小范围的垃圾回收)。首先,垃圾回收器会标记出那些“死对象”(不再被应用所引用的对象),同时延长所有保留对象的生命周期(这个生命周期长度是用数字来描述,代表了期所经历过的垃圾回收的次数)。然后,垃圾回收器会回收这些死对象,并把剩余的活着的对象移动到“幸存池”(
survivor pool
),从而清空初生池。
当一个对象存活达到一定的周期后,它就会被移动到堆中的老生代:“终身代”(
tenured pool
)。最后,当终身代被填满时,就会触发一次full gc或major gc(完全的垃圾回收),以清理终身代。
当垃圾回收(gc)执行的时候,所有应用线程都要被停止,系统产生一次暂停。minor gc非常频繁,所以被优化的能够快速的回收死对象,是新生代的内存的主要的回收方式。major gc运行起来就相对慢得多,因为要扫描非常多的活着的对象。垃圾回收器本身也有多种实现,有些垃圾回收器在一定情况下能更快的执行major gc。
堆的大小是动态的,只有堆需要扩张的时候才会从内存中分配。当堆被填满时,JVM会重新给堆分配更多的内存,直到达到堆大小的上限,这种重新分配同样会导致应用的短暂停止。
举个例子:当在程序中生成对象时,正常对象会在年轻代中分配空间,如果是过大的对象也可能会直接在年老代生成(据观测在运行某程序时候每次会生成一个十兆的空间用收发消息,这部分内存就会直接在年老代分配)。年轻代在空间被分配完的时候就会发起内存回收,大部分内存会被回收,一部分幸存的内存会被拷贝至Survivor的from区,经过多次回收以后如果from区内存也分配完毕,就会也发生内存回收然后将剩余的对象拷贝至to区。等到to区也满的时候,就会再次发生内存回收然后把幸存的对象拷贝至年老区。
10.java栈结构(java stack)
作为基于栈结构的计算机,Java栈是JVM存储信息的主要方法。当JVM得到一个java字节码应用程序后,便为该代码中一个类的每一个方法创建一个栈框架,以保存该方法的状态信息。每个栈框架包括以下三类信息:局部变量执行环境操作数栈 局部变量用于存储一个类的方法中所用到的局部变量。
Jvm栈结构如下图:
11.
JVM的被加载的过程
JVM的实质:
JVM是Java程序运行的环境,但是他同时也是操作系统的一个进程,因此他也有他自己的运行的生命周期,也有自己的代码和数据空间。
JVM在整个jdk中处于最底层,负责与操作系统的交互,用来屏蔽操作系统环境,提供一个完整的Java运行环境,因此也就虚拟计算机.操作系统装入JVM是通过jdk中Java.exe来完成,通过下面4步来完成JVM环境。
1.创建JVM装载环境和配置
2.装载JVM.dll
3.初始化JVM.dll并挂界到JNIENV(JNI调用接口)实例
4.调用JNIEnv实例装载并处理class类。
12.
JVM执行程序的过程:
I.加载.class文件
II.管理并分配内存
III.执行垃圾收集
执行java程序过程如下图所示:
13.现在流行的JVM有以下几种:
1.最为大家所熟知的JVM,其核心是:hotspot
2.sun classic/exact vm
3.sun mobile-embedded vm/meta-circular vm
4.bea jrockit/ibm j9 vm
5.azul vm/bea liquid vm
6.apache harmony/google android dalvik vm
7.microsoft jvm
8.jam VM
9.cacaoVM
10.sableVM
11.Kaffe
12.jelatine JVM
13.NanoVM
14.MRP
15.Moxie JVM
16.Jikes RVM
14.基于JVM的语言
- Scala
- Kotlin
- Jython
- Clojure
- groooy
- ceylon
- Jruby
- fantom
- Rhino
15.hotsopt JVM与Android dalvak VM比较