您的位置:首页 > 编程语言 > Java开发

Java程序的运行机制和Java虚拟机

2018-02-25 14:29 260 查看
1、java程序的运行
Java中源文件后缀为*.java,编译(也就是javac命令)使*.java文件转换为*.class文件,然后在计算机上执行(java命令)*.class文件。这就是java程序的运行过程,那么JVM(java虚拟机)是做什么用的哪?
首先我们来看一下JVM做什么用的,来看下图。JVM是读取和处理*.class文件。所有的*.class文件都是在JVM上运行的;JVM负责与不同的操作系统进行匹配。



2、JVM、 JDK、 JRE到底是什么

JVM -- java virtual machine
JVM就是我们常说的java虚拟机,它是整个java实现跨平台的 最核心的部分,所有的java程序会首先被编译为.class的类文件,这种类文件可以在虚拟机上执行,也就是说class并不直接与机器的操作系统相对应,而是经过虚拟机间接与操作系统交互,由虚拟机将程序解 释给本地系统执行。
JVM 的主要工作是解释自己的指令集(即字节码)到 CPU 的指令集或 OS 的系统调用,保护用户免被恶意程序骚扰。 JVM 对上层的 Java 源文件是不关心的,它关注的只是由源文件生成的类文件( classfile )。类文件的 组成包括 JVM 指令集,符号表以及一些补助信息。
  JRE -- java runtime environment JRE是指java运行环境。光有JVM还不能完成class的 执行,因为在解释class的时候JVM需要调用解释所需要的类库lib。 在JDK的安装目录里你可以找到jre目录,里面有两个文件夹bin和lib,在 这里可以认为bin里的就是jvm,lib中则是jvm工作所需要的类库,而jvm和 lib和起来就称为jre。所以,在你写完java程序编译成.class之后,你可以把这个.class文件 和jre一起打包发给朋友,这样你的朋友就 可以运行你写程序了。(jre里有运行.class的java.exe)

JDK -- java development kit
JDK是java开发工具包,基本上每个学java的人都会先在机器 上装一个JDK,那他都包含哪几部分呢?让我们看一下JDK的安装目录。在目录下面有 六个文件夹、一个src类库源码压缩包、和其他几个声明文件。其中,真正在运行java时起作用的 是以下四个文件夹:bin、include、lib、 jre。现在我们可以看出这样一个关系,JDK包含JRE,而JRE包 含JVM。
bin:最主要的是编译器(javac.exe)
include:java和JVM交互用的头文件
lib:类库
 jre:java运行环境
(注意:这里的bin、lib文件夹和jre里的bin、lib是 不同的)总的来说JDK是用于java程序的开发,而jre则 是只能运行class而没有编译的功能。

3、搜到的面试题目
什么是Java虚拟机?为什么Java被称作是“平台无关的编程语言”?Java虚拟机是一个可以执行Java字节码的虚拟机进程。Java源文件被编译成能被Java虚拟机执行的字节码文件。 
Java被设计成允许应用程序可以运行在任意的平台,而不需要程序员为每一个平台单独重写或者是重新编译。Java虚拟机让这个变为可能,因为它知道底层硬件平台的指令长度和其他特性。JDK、JRE、JVM关系是什么?JDK(Java Development Kit)即为Java开发工具包,包含编写Java程序所必须的编译、运行等开发工具以及JRE。开发工具如:用于编译java程序的javac命令、用于启动JVM运行java程序的java命令、用于生成文档的javadoc命令以及用于打包的jar命令等等。 
JRE(Java Runtime Environment)即为Java运行环境,提供了运行Java应用程序所必须的软件环境,包含有Java虚拟机(JVM)和丰富的系统类库。系统类库即为java提前封装好的功能类,只需拿来直接使用即可,可以大大的提高开发效率。 
JVM(Java Virtual Machines)即为Java虚拟机,提供了字节码文件(.class)的运行环境支持。 

简单说,就是JDK包含JRE包含JVM。

偶遇这道题目,觉得这个也有详述的必要,加在此处。
解释内存中的栈(stack)、堆(heap)和方法区(method area)的用法。(下面这段话虽然讲的很理论,但对于后期程序调试有很大的支撑作用)通常我们定义一个基本数据类型的变量,一个对象的引用,还有就是函数调用的现场保存都使用JVM中的栈空间;而通过new关键字和构造器创建的对象则放在堆空间,堆是垃圾收集器管理的主要区域,由于现在的垃圾收集器都采用分代收集算法,所以堆空间还可以细分为新生代和老生代,再具体一点可以分为Eden、Survivor(又可分为From Survivor和To Survivor)、Tenured;方法区和堆都是各个线程共享的内存区域,用于存储已经被JVM加载的类信息、常量、静态变量、JIT编译器编译后的代码等数据;程序中的字面量(literal)如直接书写的100、”hello”和常量都是放在常量池中,常量池是方法区的一部分,。栈空间操作起来最快但是栈很小,通常大量的对象都是放在堆空间,栈和堆的大小都可以通过JVM的启动参数来进行调整,栈空间用光了会引发StackOverflowError,而堆和常量池空间不足则会引发OutOfMemoryError。下面我们看一下 JVM运行时数据区(http://blog.csdn.net/liu88010988/article/details/50789895):第一块:PC寄存器PC寄存器是用于存储每个线程下一步将执行的JVM指令,如该方法为native的,则PC寄存器中不存储任何信息。第二块:JVM栈JVM栈是线程私有的,每个线程创建的同时都会创建JVM栈,JVM栈中存放的为当前线程中局部基本类型的变量(java中定义的八种基本类型:boolean、char、byte、short、int、long、float、double)、部分的返回结果以及Stack Frame,非基本类型的对象在JVM栈上仅存放一个指向堆上的地址第三块:堆(Heap)它是JVM用来存储对象实例以及数组值的区域,可以认为Java中所有通过new创建的对象的内存都在此分配,Heap中的对象的内存需要等待GC进行回收。第四块:方法区域(Method Area)(1)在Sun JDK中这块区域对应的为PermanetGeneration,又称为持久代。(2)方法区域存放了所加载的类的信息(名称、修饰符等)、类中的静态变量、类中定义为final类型的常量、类中的Field信息、类中的方法信息,当开发人员在程序中通过Class对象中的getName、isInterface等方法来获取信息时,这些数据都来源于方法区域,同时方法区域也是全局共享的,在一定的条件下它也会被GC,当方法区域需要使用的内存超过其允许的大小时,会抛出OutOfMemory的错误信息。第五块:运行时常量池(Runtime Constant Pool)存放的为类中的固定的常量信息、方法和Field的引用信息等,其空间从方法区域中分配。第六块:本地方法堆栈(Native Method Stacks)JVM采用本地方法堆栈来支持native方法的执行,此区域用于存储每个native方法调用的状态。这些可以通过JDK的命令行工具进行查看:可参考http://blog.csdn.net/ochangwen/article/details/52971913
参考:

[1]http://blog.csdn.net/songkai320/article/details/51819046
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: