java平台

JVM:Java Virtual Machine(Java虚拟机),负责执行符合规范的Class文件

JRE:Java Runtime Environment(java运行环境),包含JVM和类库

JDK:Java  Development Kit(java开发工具包),包含JRE和开发工具包,例如javac、javah


JVM所处的位置

(1)通常工作中所接触的基本是Java库和应用以及Java核心类库,知道如何使用就可以了,但是归根结底代码都是要编译成class文件由Java虚拟机装载执行,所产生的结果或者现象都可以通过Java虚拟机的运行机制来解释。一些相同的代码会由于虚拟机的实现不同而产生不同结果。

(2)在Java平台的结构中,可以看出,Java虚拟机(JVM)处在核心的位置,是程序与底层操作系统和硬件无关的关键。它的下方是移植接口,移植接口由两部分组成:适配器和Java操作系统,其中依赖于平台的部分称为适配器;JVM通过移植接口在具体的平台和操作系统上实现;在JVM的上方是Java的基本类库和扩展类库以及它们的API, 利用Java API编写的应用程序(application)和小程序(Java applet)可以在任何Java平台上运行而无需考虑底层平台,就是因为有Java虚拟机(JVM)实现了程序与操作系统的分离,从而实现了Java的平台无关性。

(3)对JVM规范的的抽象说明是一些概念的集合,它们已经在书《The Java Virtual Machine Specification》(《Java虚拟机规范》)中被详细地描述了;对JVM的具体实现要么是软件,要么是软件和硬件的组合,它已经被许多生产厂商所实现,并存在于多种平台之上;运行Java程序的任务由JVM的运行期实例单个承担。

(4)JVM可以由不同的厂商来实现。由于厂商的不同必然导致JVM在实现上的一些不同,像国内就有著名的TaobaoVM;然而JVM还是可以实现跨平台的特性,这就要归功于设计JVM时的体系结构了。

(5)JVM在它的生存周期中有一个明确的任务,那就是装载字节码文件,一旦字节码进入虚拟机,它就会被解释器解释执行,或者是被即时代码发生器有选择的转换成机器码执行,即Java程序被执行。因此当Java程序启动的时候,就产生JVM的一个实例;当程序运行结束的时候,该实例也跟着消失了。




Java虚拟机的体系结构

      一个JVM实例的行为不光是它自己的事,还涉及到它的子系统、存储区域、数据类型和指令这些部分,它们描述了JVM的一个抽象的内部体系结构,其目的不光规定实现JVM时它内部的体系结构,更重要的是提供了一种方式,用于严格定义实现时的外部行为。每个JVM都有两种机制,一个是装载具有合适名称的类(类或是接口),叫做类装载子系统;另外的一个负责执行包含在已装载的类或接口中的指令,叫做运行引擎。每个JVM又包括方法区、堆、Java栈、程序计数器和本地方法栈这五个部分,这几个部分和类装载机制与运行引擎机制一起组成的体系结构图为:

 

      Java虚拟机定义了若干种程序运行期间会使用到的运行时数据区,其中有一些会随着虚拟机启动而创建,随着虚拟机退出而销毁。另外一些则是与线程一一对应的,这些与线程对应的数据区域会随着线程开始和结束而创建和销毁。

可以看出Java虚拟机的运行时数据区包括了:方法区、Java堆、Java虚拟机栈、PC寄存器、本地方法栈,还有常量池。它们被分为两大类-----线程共享、私有数据区。

1.线程共享数据区

包括:Java堆、方法区、常量池。它们会随着虚拟机启动而创建,随着虚拟机退出而销毁。

(1)Java堆

       Java堆在虚拟机启动的时候被创建,Java堆主要用来为类实例对象和数组分配内存。Java虚拟机规范并没有规定对象在堆中的形式。

     在Java中,堆被划分成两个不同的区域:新生代( Young )、老年代( Old );这也就是JVM采用的“分代收集算法”,简单说,就是针对不同特征的java对象采用不同的策略实施存放和回收,自然所用分配机制和回收算法就不一样。新生代( Young ) 又被划分为三个区域:Eden、From Survivor、To Survivor。

       分代收集算法:采用不同算法处理[存放和回收]Java瞬时对象和长久对象。大部分Java对象都是瞬时对象,朝生夕灭,存活很短暂,通常存放在Young新生代,采用复制算法对新生代进行垃圾回收。老年代对象的生命周期一般都比较长,极端情况下会和JVM生命周期保持一致;通常采用标记-压缩算法对老年代进行垃圾回收。

       这样划分的目的是为了使JVM能够更好的管理堆内存中的对象,包括内存的分配以及回收。

    Java堆可能发生如下异常情况:如果实际所需的堆超过了自动内存管理系统能提供的最大容量,那Java虚拟机将会抛出一个OutOfMemoryError异常。 

(2)方法区

      方法区在虚拟机启动的时候被创建,它存储了每一个类的结构信息,例如运行时常量池、字段和方法数据、构造函数和普通方法的字节码内容、还包括在类、实例、接口初始化时用到的特殊方法。 

      方法区可能发生如下异常情况: 如果方法区的内存空间不能满足内存分配请求,那Java虚拟机将抛出一个OutOfMemoryError异常. 

(3)常量池

      运行时常量池(Runtime Constant Pool)是每一个类或接口的常量池的运行时表示形式,它包括了若干种不同的常量:从编译期可知的数值字面量到必须运行期解析后才能获得的方法或字段引用。运行时常量池在方法区中。

      在创建类和接口的运行时常量池时,可能会发生如下异常情况:当创建类或接口的时候,如果构造运行时常量池所需要的内存空间超过了方法区所能提供的最大值,那Java虚拟机将会抛出一个OutOfMemoryError异常。

2.线程私有数据区

     包括:PC寄存器、JVM栈、本地方法区。它们是与线程一一对应的,这些与线程对应的数据区域会随着线程开始和结束而创建和销毁。

(1)PC寄存器

      每个Java虚拟机线程都有自己的PC寄存器。在某个线程被新建时,会获得一个PC寄存器。线程当前执行的方法称为当前方法,PC寄存器用来存放当前方法中当前执行的字节码指令的地址;之所以为每一个线程都分配一个PC寄存器,试想:多线程运行时,某个时间片内只执行一个线程,CPU在不停的切换多个线程,那如何记录具体每一个线程上一次执行到哪个位置了呢,这时候PC寄存器用来存放当前方法中当前执行的字节码指令的地址,就完美解决了,这就是为什么PC寄存器是线程私有数据区的原因。

      如果当前方法是本地方法(Native),那么寄存器存放undefined。寄存器的大小至少应该能够存放一个returnAddress类型的数据或者与平台相关的本地指针的值。

PC寄存器是惟一一个没有明确规定需要抛出OutOfMemoryError异常的运行时数据区。

(2)JVM栈

       每个Java虚拟机线程都有自己的Java虚拟机栈。Java虚拟机栈用来存放栈帧,而栈帧主要包括了:局部变量表、操作数栈、动态链接。Java虚拟机栈允许被实现为固定大小或者可动态扩展的内存大小。

       Java虚拟机使用局部变量表来完成方法调用时的参数传递。局部变量表的长度在编译期已经决定了并存储于类和接口的二进制表示中,一个局部变量可以保存一个类型为boolean、byte、char、short、float、reference和returnAddress的数据,两个局部变量可以保存一个类型为long和double的数据。

  Java虚拟机提供一些字节码指令来从局部变量表或者对象实例的字段中复制常量或变量值到操作数栈中,也提供了一些指令用于从操作数栈取走数据、操作数据和把操作结果重新入栈。在方法调用的时候,操作数栈也用来准备调用方法的参数以及接收方法返回结果。

  每个栈帧中都包含一个指向运行时常量区的引用支持当前方法的动态链接。在Class文件中,方法调用和访问成员变量都是通过符号引用来表示的,动态链接的作用就是将符号引用转化为实际方法的直接引用或者访问变量的运行是内存位置的正确偏移量。 

        总的来说,Java虚拟机栈是用来存放局部变量和过程结果的地方。 

       Java虚拟机栈可能发生如下异常情况: 如果Java虚拟机栈被实现为固定大小内存,线程请求分配的栈容量超过Java虚拟机栈允许的最大容量时,Java虚拟机将会抛出一个StackOverflowError异常。 

       如果Java虚拟机栈被实现为动态扩展内存大小,并且扩展的动作已经尝试过,但是目前无法申请到足够的内存去完成扩展,或者在建立新的线程时没有足够的内存去创建对应的虚拟机栈,那Java虚拟机将会抛出一个OutOfMemoryError异常。 

(3)本地方法区

       本地方法栈用于支持native方法的运行。(native方法,比如用C/C++实现的代码)


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值