java组成部分_[Java] Java虚拟机组成部分

每个Java程序都运行于某个具体的Java虚拟机实现的实例上。

当启动一个Java程序时,一个虚拟机实例就诞生了,当该程序关闭退出,这个虚拟机实例就随之消亡。如果同一台计算机上同时运行3个Java程序,将得到3个Java虚拟机实例。每个程序都运行于它自己的Java虚拟机实例中。

Java虚拟机实例通过调用某个初始类的main方法来运行一个Java程序。这个main方法必须是public,static,接受String[]作为参数,返回void。任何拥有这样一个main方法的类都可以作为Java程序运行的起点。

class Test{

public static void main(String[] args){

//

}

}

告诉Java虚拟机要运行的Java程序中初始类的名字后,整个程序将从它的main方法开始执行。

java Test Hello world

则args[0]="Hello",args[1]="world"

main方法是程序初始线程的起点,任何其他线程都是由这个初始线程启动的。

Java虚拟机内部有两种线程,非守护线程和守护线程。

从main开始的初始线程是非守护线程,只要还有任何非守护线程在运行,这个Java程序就继续运行。当程序中所有的非守护线程都终止时,虚拟机实例将自动退出。

守护线程通常是由虚拟机自己使用,比如执行垃圾收集任务的线程。Java程序也可以把它创建的任何线程标记为守护线程。

Java虚拟机体系结构由4部分构成:子系统,内存区,数据类型,指令。

每个Java虚拟机都有一个类装载器子系统,它根据给定的全限定名来装入类型。

每个Java虚拟机都有一个执行引擎,它负责执行那些包含在被装载的方法中的指令。

3d584a5b546b

某些运行时数据是由程序中的所有线程共享的,还有一些则只能由一个线程拥有。

方法区和堆,是由该虚拟机实例中所有线程共享的。

虚拟机会从装载的二进制文件中解析类型信息放到方法区中,把该程序运行时创建的对象都放到堆中。

每一个新线程被创建时,都将得到它自己的程序指针寄存器(PC)以及一个Java栈。

如果线程正在执行的是一个Java方法(非本地方法),那么PC指向下一条被执行的指令,而Java栈总是存储该线程中Java方法的调用状态。

本地方法调用状态,则是以某种依赖于具体实现的方式存储在本地方法栈中,也可能是寄存器或者其他特定实现相关的内存区中。

Java栈由许多帧(frame)组成,帧中包含了Java方法的调用状态。当线程调用一个Java方法时,虚拟机压入一个新的frame到该线程的Java栈中,该方法返回时,这个frame从Java栈中弹出并抛弃。

Java虚拟机为每一个线程创建的内存区是私有的,任何线程都不能访问其他线程的PC或Java栈。

3d584a5b546b

线程1,2正在执行Java方法,它们的PC分别指向下一条将被执行的指令。

线程3正在执行一个本地方法,它的PC值是不确定的。

Java虚拟机中的数据类型分为两种:基本类型和引用类型。

基本类型的变量持有原始值,而引用类型的变量持有引用值。

3d584a5b546b

关于基本类型boolean,当编译器把Java源码编译为字节码时,会用int或byte表示boolean。在Java虚拟机中,false是用整数0来表示的,所有非零整数都是true。涉及boolean的操作则会使用int,boolean数组是当做byte数组访问的。

基本类型returnAddress,是只在虚拟机内部使用的基本类型,用来实现Java程序中的finally字句。

其他基本类型都是数值类型,包括整数类型,浮点数类型。

注:

基本类型的数据不能看作对象,存放在栈中。基本类型都对应有包装类,包装类就是对象了,分配在堆中,栈中保存的是堆内对象的引用。引入包装类的目的是为了让这些数据具有对象性质,可以调用对象的方法。

引用类型有3种:类类型,接口类型,数组类型,还有一种特殊的引用值null。

类装载器子系统,负责查找并装载类型。

Java虚拟机有两种类装载器:启动类装载器和用户自定义类装载器。前者是Java虚拟机实现的一部分,后者是一个普通的Java对象。

由不同的类装载器装载的类,会放在虚拟机内部的不同命名空间中。

对于每一个被装载的类型,Java虚拟机都会在内存堆中为它创建一个java.lang.Class类的实例来代表该类型,而装载的类型信息则都位于方法区。

每个类装载器都有自己的命名空间,其中维护着由它装载的类型。所以,一个Java程序可以多次装载具有同一个全限定名的类型,类型的全限定名不足以确定它在Java虚拟机中的唯一性。对于每一个被装载的类型,Java虚拟机都会记录装载它的类型装载器。

当虚拟机装载某个类型时,先使用类装载器定位并读取相应的字节码文件,然后提取其中的类型信息,将这些类型信息和类的静态变量存储到方法区中。

由于所有线程都共享方法区,因此方法区中的数据访问必须被设计为线程安全的。假设同时有两个线程来访问一个类,而这个类还没有被装载,那么,只应该有一个线程去装载它,另一个线程等待。

在Java源码中,全限定名由类所属的包的名称加一个“.”再加上类名组成。

一个Java程序独占一个Java虚拟机实例,每个Java虚拟机实例都有自己的堆空间,堆空间由Java程序的各线程共享。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值