虚拟机的概念相当宽泛。通常人们会接触到虚拟机的概念,比如像VMware这样的硬件模拟软件,以及像JVM这样的硬件与编译器之间的软件。这里指的是后者。
虚拟机是一台抽象的计算机,它像实际的计算机一样,有一个指令集,使用不同的存储区域。它负责执行指令和管理数据、内存和寄存器。这个虚拟机为编译器提供了任何平台上的通用接口。编译器只需要面对虚拟机,生成虚拟机能够理解的代码,然后解释器将虚拟机代码转换成特定系统的机器码执行。
比较通俗的回答(适合没有计算机基础的朋友)
虚拟机,顾名思义,就是虚拟计算机。这个虚拟计算机和真实计算机几乎一模一样。不同的是他的硬盘被虚拟化成了一个文件,你可以随意修改虚拟机的设置而不用担心给自己的电脑造成损失,所以可以用来做实验什么的。呵呵,差不多是这样的。不知道能不能听懂我说的话。简单来说就是一台虚拟电脑。你可以做任何事。现在来说说虚拟机的软件,主要有Virtual PC和VMware。软件的选择也是有门道的。呵呵,简单来说,VPC的设定很简单,一路到下就够了。VM的设置比较麻烦,但也不是很多麻烦,但是VM性能更好,可以说和真正的电脑性能一模一样。也可以和现在的电脑桥接互联,有更多的东西可以学习,呵呵
比较专业的回答(适合稍微有点计算机基础的朋友)
取出一台计算机上的部分硬盘和内存,创建几个虚拟机,每个虚拟机都可以运行自己的操作系统,互不干扰。这些“新”机器有自己独立的CMOS、硬盘和操作系统,你可以像普通机器一样分区、格式化、安装系统和应用软件,把这些操作系统连接成一个网络。虚拟系统崩溃后,可以直接删除,不影响原生系统。同样,原生系统崩溃后,也不会影响到虚拟系统。您可以在下次重新安装后添加上一个虚拟系统。同时也是唯一可以在Windows和Linux主机平台上运行的虚拟计算机软件。虚拟机软件不需要重启就可以在同一台计算机上使用多个OSS,既方便又安全。虚拟机在学习技术方面可以起到很大的作用。
虚拟机(虚拟机)
虚拟机(VM)是一种支持在单个物理服务器上并行运行多个操作系统的系统,可以更有效地利用底层硬件。在虚拟机中,CPU芯片将存储区域与系统的其他部分分开,操作系统和应用程序在“保护模式”环境下运行。如果一个程序在虚拟机中冻结,不会影响虚拟机外的程序运行和操作系统的正常运行。虚拟机有四种架构。首先是“一对一映射”,其中IBM虚拟机最为典型。第二种是由机器虚拟指令映射组成,其中Java虚拟机最为典型。Unix虚拟机模型和OSI虚拟机模型可以直接映射一些指令,其他的可以直接调用操作系统函数。
在真实的计算机系统中,操作系统中的设备驱动程序控制硬件资源,并负责将系统指令转换成特定的设备控制语言。在设备所有权独立的假设下,形成了驱动,使得在一台计算机上不可能同时运行多个操作系统。虚拟机包含克服这一限制的技术。虚拟化过程引入了低层设备的资源重定向交互,不影响高层应用层。虚拟机允许客户在一台计算机上同时运行多个操作系统。
微软虚拟服务器2005基于OSI虚拟机结构,主要包括以下几点:
主机操作系统,如Windows Server 2003,主要控制主机系统。
虚拟机操作系统(如虚拟服务器2005)包含用于控制虚拟机的VMM虚拟层,为硬件模拟提供软件结构。
每个虚拟机由一组虚拟化设备组成,其中每个虚拟机都有相应的虚拟硬件。
来宾操作系统和应用程序可以在虚拟机上运行,无需任何交互式网络适配器的支持。虚拟服务器只是物理以太网中的一种软件仿真设备。
java虚拟机
1.什么是Java虚拟机
Java虚拟机是一个假想的机器,在真实的计算机上通过软件仿真实现。Java虚拟机有自己想象的硬件,比如处理器、栈、寄存器等。并且也有相应的指令系统。
1.为什么使用Java虚拟机
Java语言的一个非常重要的特性是它独立于平台。使用Java虚拟机是实现这一特性的关键。一般的高级语言如果要在不同的平台上运行,需要编译成不同的目标代码。随着Java虚拟机的引入,Java在不同平台上运行时不需要重新编译。Java语言使用模式Java虚拟机屏蔽了与特定平台相关的信息,使得Java语言编译器只需生成运行在Java虚拟机上的目标代码(字节码),就可以在各种平台上运行,无需修改。Java虚拟机在执行字节码时,将字节码解释为特定平台上的机器指令。
2.谁需要了解Java虚拟机
Java虚拟机是Java语言底层实现的基础。任何对Java语言感兴趣的人都应该对Java虚拟机有一个大概的了解。这有助于理解Java语言的一些性质,有助于使用Java语言。对于想在特定平台上实现Java虚拟机的软件人员,Java语言的编译器作者,以及想用硬件芯片实现Java虚拟机的人,必须对Java虚拟机的规范有深入的了解。另外,如果想扩展Java语言或者把其他语言编译成Java语言的字节码,还需要对Java虚拟机有深入的了解。3.Java虚拟机支持的数据类型
Java虚拟机支持的Java语言基本数据类型如下:
字节://1/1字节有符号整数的补码
short ://2/2字节有符号整数的补码
Int://4字节有符号整数的4/补码
long ://8/8字节有符号整数的补码
Float://4字节IEEE754单精度浮点数
Double://8字节IEEE754双精度浮点数
Char://2字节无符号Unicode字符
几乎所有的Java类型检查都是在编译时完成的。上面列出的原始数据类型的数据在执行Java时不需要用硬件来标记。操作这些原始数据类型的字节码(指令)已经指出了操作数的数据类型。例如,iadd、ladd、fadd和dadd指令都是两个数相加,它们的操作数类型是int、long、float和double。虚拟机不会为布尔类型设置单独的指令。布尔数据由整数指令处理,包括整数返回。布尔数组是用字节数组处理的。虚拟机使用IEEE754格式的浮点数。不支持IEEE格式的老式计算机在运行Java数值计算程序时可能会非常慢。
虚拟机支持的其他数据类型包括:
对象//对Javaobject(对象)的4字节引用
返回地址//4字节,用于jsr/ret/jsr-w/ret-w指令
注意:Java数组被视为对象。
虚拟机的规范对对象的内部结构没有特殊要求。在Sun的实现中,对对象的引用是一个句柄,它包含一对指针:一个指针指向对象的方法表,另一个指针指向对象的数据。用Java虚拟机的字节码表示的程序要符合类型规定。Java虚拟机的实现应该拒绝执行违反类型规定的字节码程序。Java虚拟机由于字节码定义的限制,只能在32位地址空间的机器上运行。但是你可以创建一个Java虚拟机,它自动将字节码转换成64位格式。从Java虚拟机支持的数据类型可以看出,Java严格规定了数据类型的内部格式,使得各种Java虚拟机对数据的解释是一致的,从而保证了Java的平台独立性和可行性移植性。
二、Java虚拟机架构
Java虚拟机由五部分组成:一组指令集、一组寄存器、一个堆栈、一个垃圾收集堆和一个方法区。这五个部分是Java虚拟机的逻辑组件,不依赖于任何实现技术或组织,但它们的功能必须在真实机器上以某种方式实现。
1.Java指令集
Java虚拟机支持大约248个字节码。每个字节码执行一个基本的CPU操作,比如给寄存器加一个整数,子程序转移等等。Java指令集相当于Java程序的汇编语言。
Java指令集中的指令包含一个单字节运算符来指定要执行的操作,以及0个或更多操作数来提供操作所需的参数或数据。许多指令没有操作数,仅由单字节运算符组成。
虚拟机内部循环的执行过程如下:
do{
取一个运算符字节;
根据运算符的值;
}while(程序未完成)
由于指令系统的简单性,虚拟机执行的过程非常简单,有利于提高执行效率。指令中操作数的数量和大小由运算符决定。如果操作数大于一个字节,其存储顺序首先是高字节。例如,16位参数在存储时占用两个字节,其值为:
第一字节*256和第二字节字节码指令流通常仅是字节对齐的。例外情况是tabltch和lookup指令,其中要求强制4字节边界对齐。
2.注册
Java虚拟机的寄存器用来保存机器的运行状态,类似于微处理器中的一些特殊寄存器。
Java虚拟机中有四种:寄存器
Pc:Java程序计数器。
Optop:指向操作数堆栈顶部的指针。
Frame:是指向当前执行方法的执行环境的指针。
Vars:是指向当前正在执行的方法的局部变量区域中的第一个变量的指针。
java虚拟机
Java虚拟机是栈式的,不定义也不使用寄存器传递或接受参数。其目的是保证指令集的简单性和实现的高效性(特别是对于寄存器很少的处理器)。
所有寄存器都是32位的。
3.一堆
Java虚拟机的栈有三个区域:局部变量区、运行环境区和操作数区。
(1)局部变量区域每个Java方法都使用一组固定大小的局部变量。它们由vars寄存器的字偏移来寻址。局部变量都是32位的。长整数和双精度浮点数占用两个局部变量的空间,但根据第一个局部变量的索引进行寻址。(比如一个索引为n的局部变量,如果是双精度浮点数,实际上占用了索引n和n ^ 1表示的存储空间。虚拟机规范不要求局部变量中的64位值是64位对齐的。虚拟机提供将局部变量中的值加载到操作数堆栈中的指令,还提供将操作数堆栈中的值写入局部变量的指令。(2)运行环境区域包含的信息用于动态链接、正常方法返回和异常传播。
动态连接
运行时环境包括指向当前类和当前方法的解释器符号表的指针,用于支持方法代码的动态链接。方法的类文件代码在引用要调用的方法和要访问的变量时使用符号。动态链接将符号方法调用转换为实际方法调用,加载必要的类来解释未定义的符号,并在运行时将变量访问转换为与这些变量的存储结构相对应的偏移地址。动态链接方法和变量使得方法中使用的其他类的变化不影响这个程序的代码。
正常方法返回
如果当前方法正常结束,当执行正确类型的返回指令时,被调用的方法将获得返回值。执行环境用于在正常返回下恢复调用者的寄存器,并将调用者的程序计数器增加一个合适的值来跳过已执行的方法调用指令,然后在调用者的执行环境中继续执行。
异常和错误传播
异常在Java中称为Error或Exception,是Throwable类的子类。在程序中,原因是:动态链接错误,比如找不到需要的类文件。运行时错误,例如对空指针的引用
该程序使用throw语句。
出现异常时,Java虚拟机采取以下措施:
检查与当前方法关联的catch子句表。每个catch子句都包含其有效的指令范围、可以处理的异常类型以及处理异常的代码块地址。
匹配异常的catch子句应满足以下条件:导致异常的指令在其指令范围内,发生的异常类型是它可以处理的异常类型的子类型。如果找到匹配的catch子句,系统将转移到指定的异常处理块执行;如果没有找到异常处理块,重复查找匹配catch子句的过程,直到检查完当前方法的所有嵌套catch子句。
由于虚拟机继续从第一个匹配的catch子句开始执行,因此catch子句表中的顺序非常重要。因为Java代码是结构化的,所以某个方法的所有异常处理程序总是可以按顺序排列在一个表中。对于任何可能的程序计数器值,可以以线性顺序找到合适的异常处理块来处理程序计数器值下的异常情况。
如果找不到匹配的catch子句,当前方法将获得一个“未截获异常”的结果,并将其返回给当前方法的调用方,就像该异常刚刚发生在它的调用方一样。如果在调用者中仍然没有找到相应的异常处理块,这种错误传播将继续。如果错误传播到顶层,系统将调用默认的异常处理块。
(3)操作数栈机器指令只从操作数栈中取出操作数,对其进行运算,并将结果返回到栈中。之所以选择堆栈结构,是因为:可以在只有少量寄存器或非通用寄存器的机器上(比如Intel486)高效地模拟虚拟机的行为。操作数堆栈是32位。它用于将参数传递给方法,并从方法接收结果。它还用于支持操作参数和保存操作结果。例如,iadd指令将两个整数相加。添加的两个整数应该是操作数堆栈顶部的两个字。这两个字被之前的指令推到栈上。这两个整数将从堆栈中弹出,相加,并将结果推回操作数堆栈。
每种原始数据类型都有特殊的指令来对其执行必要的操作。每个操作数在堆栈中需要一个存储位置,除了长型和双型需要两个位置。操作数只能由适合其类型的运算符操作。例如,如果两个int类型的数字被视为long类型的数字,则按下这两个数字是非法的。在Sun的虚拟机实现中,这个限制是由字节码验证器强制实施的。但是,有一些操作(操作符复制和交换)用于操作运行时数据区,而不管其类型如何。4.垃圾收集堆
Java的堆是一个运行时数据区,类的实例(对象)从中分配空间。Java语言有垃圾收集能力:没有给程序员显式释放对象的能力。Java没有指定具体的垃圾收集算法,可以根据系统的要求使用各种算法。
5.方法区域
方法区类似于传统语言中的编译代码或Unix进程中的主体段。它保存方法代码(编译后的java代码)和符号表。在当前的Java实现中,方法代码不包含在垃圾收集堆中,但计划在未来版本中实现。每个类文件包含一个Java类或一个Java接口的编译代码。可以说一个类文件就是Java语言的执行代码文件。为了保证类文件的平台独立性,Java虚拟机规范中也详细说明了类文件的格式。具体请参考Sun公司的Java虚拟机规范。
客服支持
微信咨询
售后