`
tangkuo
  • 浏览: 100358 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
文章分类
社区版块
存档分类
最新评论

Java的运行原理

 
阅读更多

在Java中引入了虚拟机的概念,即在机器和编译程序之间加入了一层抽象的虚拟的机器。这台虚拟的机器在任何平台上都提供给编译程序一个的共同的接口。编译程序只需要面向虚拟机,生成虚拟机能够理解的代码,然后由解释器来将虚拟机代码转换为特定系统的机器码执行。在Java中,这种供虚拟机理解的代码叫做字节码(ByteCode)(class文件的内容),它不面向任何特定的处理器,只面向虚拟机。每一种平台的解释器是不同的,但是实现的虚拟机是相同的。Java源程序经过编译器编译后变成字节码,字节码由虚拟机解释执行,虚拟机将每一条要执行的字节码送给解释器,解释器将其翻译成特定机器上的机器码,然后在特定的机器上运行。



跨平台:

话说,在北京,一般都是讲北京话的,上海,一般都是将上海话,广东,广东话...
现有一公文发出,要全国执行,该当如何?——先统一翻译成普通话。各地在将普通话版本翻译成当地的方言。

这里,北京、上海就是不同类型的机器windows,linux...
编译(javac)就是将公文翻译成普通话的过程,而编译出的.class文件,就是公文的普通话版本。
在执行的时候,各地的翻译就是jvm,负责将.class转换成本地能够理解的方言来执行。

*.java→*.class→机器码


Java源文件(*.java)——>Java编译器——>字节码文件(*.class)——>类装载器——>字节码校检器—— >解释器——>操作系统(Windows、Linux等)整个文件Load到内存区,一系列动作之后形成操作系统认识的代码,操作系统找到 main方法开始实行。

heap——>new 出来的东西放在这里

stack——>局部变量

data segment——>静态变量或字符串常量

code segment——>存放代码



局部变量:方法或是语句块内部定义的变量(local variable)

成员变量:方法外部、类内部定义的变量,也叫做全局变量(glbal valiable)




java编译器 (编译) → 虚拟机(解释执行) →  解释器(翻译) → 机器码

Java虚拟机(JVM)

Java虚拟机(JVM)是Java Virtual Machine的缩写,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能模拟来实现的。

Java中,类加载器把一个类装入JAVA虚拟机需要经过三个步骤来完成:装载、链接、初始化,其中链接又分来校验、准备、解析过程

装载:查找和导入.class文件

链接:检查装入.class文件的正确性,然后,java虚拟机为变量分配内存,设置默认值

初始化:把符号引用变成直接引用。。。
复制代码

1 public class  Main { 
2
3 private static int size=1; 
4
5 public static void main(String args[]) {  
6
7 User u = new User(); 
8
9 u.setName("李文水"); 
10
11 u.setPwd("159"); 
12
13 String name = u.getName(); 
14
15 String pwd = u.getPwd(); 
16
17 u = null; 
18
19 } 
20
21 } 
22
23 public class User { 
24
25 private String name; 
26
27 private String pwd; 
28
29 public String getName() { 
30
31 return name; 
32
33 } 
34
35 public void setName(String name) { 
36
37 this.name = name; 
38
39 } 
40
41 public String getPwd() { 
42
43 return pwd; 
44
45 } 
46
47 public void setPwd(String pwd) { 
48
49 this.pwd = pwd; 
50
51 } 
52
53 }

复制代码



现在假设这两个java源文件已经被编译成了CLASS文件了,我们来看看java虚拟机怎么执行的。

Java虚拟机工作流程:

1.装载

描叙:Java虚拟机装载指定的CLASS文件

结果:形成这个CLASS类的实例对象

过程:java虚拟机使用类装载器定位到相应的CLASS文件,然后读取这个CLASS文件(一个线性二进制数据流),将它传入java虚拟机中。紧接着虚拟机提取其中的类型信息。比如:该类的类名,方法名,变量名,修饰符,方法的返回类型等等。还有一个重要的东西就是常量池。(常量池保存了该类型的所有常量,包括直接常量和对其他类型,字段,方法的符号引用)将这些信息保存在一个叫做方法区的地方。最终形成CLASS类的实例,这个实例存放在内存的堆区。它成为了java程序与内部数据结构之间的接口,程序要访问该类型的信息,程序就调用该类型对应的CLASS实例对象的方法。简而言之:这个过程就是把一个类型的二进制数据解析为方法区中的内部数据结构,并在堆上建立一个CLASS对象的过程。

示例:装载Main类

Java虚拟机读取Main类的CLASS文件,生产对应的java.lang.Class类的实例,读取其中的类型信息,比如修饰符 private,public,static,另外变量 size,name,pwd,User(User即为一个引用)共同构成了这个类的常量池。将这些信息保存在方法区,

2.链接

描述:验证,准备,解析(可选)

结果:这个类型是正确的。(这里不知道该怎么描述)

过程:

1)验证:确定类型符合java语言的语义,比如:final类不能有子类,final方法不能被覆盖,确保在类型和超类型之间没有不兼容的方法声明(比如两个方法拥有同样的名字,参数完全相同,但返回类型不同)。

2)准备:java虚拟机为类变量分配内存,设置默认值

3)解析:在类型的常量池中寻找类,接口,字段和方法的符合引用把这些符号引用替换成直接引用的过程。

示例: 连接Main类

Java虚拟机为size分配内存,并赋默认值0.找到常量池中User类的引用,如果User类还没有被装载,则装载并且连接该类,然后将常量池中对User类的引用替换为直接引用。在此时User类并不会被初始化,因为还没有用它。

3.初始化

描述:初始化一些静态变量

结果:这个类型可以使用了

过程:可能会调用()方法,(这个方法只能够由java虚拟机调用)来初始化该类的静态变量。在调用这个方法前,必须确认该类的超类的() 方法已经被调用。

示例:初始化Main类

Java虚拟机将Main类的静态变量赋值为1.

4.使用(执行该类代码了)

1.User u = new User();(存放在内存的堆区)

创建了一个User类实例,实际上是通过这个类的CLASS实例实例化的。方法如下:

User u=(User)Class.forName("User").newInstance();

为了方便,用C代替Class.forName("User")

2.u.setName("李文水"); u.setPwd("159");

调用该类的方法,为该类的变量赋值,Java虚拟机内部调用是这样的,通过方法区找到该方法,利用CLASS实例的如下方法调用:

c.getMethod("setName").invoke(u,"李文水");

3.String name = u.getName(); String pwd = u.getPwd();

与第二步类似,不同的是将取得的值分别赋给了变量name和pwd。关键是这个值保存在哪里?和实例对象一样,存放在堆区。这个时候我应该可以看出CLASS实例的作用了,它就是起个中间作用,将程序中的调用反应到堆区上数据的变化。

4.u = null;


这个步骤写出来的目的是了解一下Java虚拟机垃圾回收机制。(没有什么实际意义)

Java虚拟机内部会根据一种规则(这个对象是否可以触及)来判断这两个类是否可以回收了?具体形式如下:



当执行 u = null;时这条线就被斩断了,因此User实例就不可以触及了,所以java虚拟机就可以回收这个User实例了
一步一个脚印,方便自己复习,该出手时就出手,有错误,一定要指正,非常感谢,共同进步!


分享到:
评论

相关推荐

    java运行原理图

    亿图软件绘制的Java基本运行原理图示,避免张贴图片格式,便于适应文档的撰写。简单明了的使用和修改

    Java运行原理与Java虚拟机.pdf

    ### Java运行原理与Java虚拟机 #### 一、Java运行原理概述 Java作为一种跨平台的编程语言,其独特之处在于它的编译和解释过程。Java程序的执行涉及到两个主要步骤:首先是编译阶段,其次是解释执行阶段。 1. **...

    Java运行原理 javap命令运行结果

    ### Java运行原理与javap命令运行结果解析 #### 一、Java运行原理概述 Java是一种广泛使用的编程语言,它的程序可以在任何支持Java虚拟机(JVM)的操作系统上运行,而无需重新编译。Java程序的执行过程可以分为...

    Java运行原理 demo代码

    Java运行原理 demo代码

    01-JavaSE-JAVA运行原理.ppt

    Java是由Sun公司推出的Java程序设计语言和Java软件开发平台的总称。... 高性能:运行速度随着编译器技术提高 ; 多线程:java内置了对多 线程的支持,编写更简单; 动态性:适应动态变化的环境。

    Java环境搭建和运行原理

    eclipse的安装和JDK的安装以及Java环境的搭建,另外还介绍了Java的运行原理 一,安装Java开发环境 1.下载安装配置JDK a 从Oracle网站下载JDK b安装JDK c配置JDK 2.下载安装Eclipse

    java内存原理.doc

    Java 内存原理 Java 内存原理是 Java 语言中的一种基本机制,用于管理和分配内存资源。在 Java 中,内存被分为两种:栈内存和堆内存。 栈内存是指在函数中定义的一些基本类型的变量和对象的引用变量。这些变量在...

    浅谈为什么java命令运行class文件出现异常共7页.p

    Java命令行运行class文件是Java开发中的基本操作,但有时候我们可能会遇到各种异常情况,导致程序无法正常执行。本文将深入探讨这个问题,...不断积累经验,理解Java运行原理,将有助于我们更高效地定位和解决问题。

    java core 笔记

    2. Java运行原理 - 编译与解释:Java源代码首先被编译成字节码(.class文件),然后由JVM解释执行。 - 类加载:JVM在运行时动态加载类,实现程序的动态扩展。 - JIT编译:JVM的即时编译器将频繁执行的热点代码...

    Java教案——3章 个人学习资料

    Java运行原理主要包括以下几个步骤: 1. **编译过程**:Java源文件(.java)通过Java编译器(javac)被编译成字节码(.class)。 2. **运行过程**:客户端收到网络传输的字节码后,通过JRE中的JVM将字节码转化为本地...

    【一脚揣进J2SE】视频教程(持续更新)

    资源名称:【一脚揣进J2SE】视频教程(持续更新)资源目录:【】《一脚踹进J2SE》1-1Java简介【】《一脚踹进J2SE》1-2Java运行环境搭建【】《一脚踹进J2SE》1-3HelloWorld实现及Java运行原理介绍【】《一脚踹进J2SE...

    深入Java核心 Java内存分配原理精讲

    深入探讨Java核心:Java内存分配原理精讲 Java内存分配机制是Java编程语言的重要组成部分,它不仅直接影响着程序的性能,也是理解Java垃圾回收、内存泄漏等问题的关键。本文将聚焦于Java内存分配的核心概念,包括栈...

    java反射原理详解

    Java反射机制是Java语言的一种强大的特性,它允许程序在运行时动态地获取类的信息并操作类的对象。在Java中,反射主要涉及到`java.lang.Class`类、`java.lang.reflect`包中的类(如Constructor、Method、Field)以及...

    Java运行时内存分配

    ### Java运行时内存分配详解 #### 一、引言 Java作为一种广泛使用的编程语言,其内存管理机制一直是开发者关注的重点之一。Java程序在运行时如何分配内存?对象是如何存储的?这些问题不仅对于深入理解Java虚拟机...

    Java运行环境Java运行环境

    Java运行环境是执行Java程序所必需...Java运行环境是Java开发和运行的基础,理解其工作原理和特点对于Java程序员来说至关重要。无论是编写简单的控制台程序,还是构建复杂的分布式系统,Java运行环境都扮演着关键角色。

    Java运行时动态编译

    Java运行时动态编译是Java语言的一个重要特性,它使得Java程序在运行过程中可以对代码进行优化和调整,极大地提高了程序的性能。这个特性主要得益于Java的Just-In-Time (JIT) 编译器,它是Java虚拟机(JVM)的一部分...

    JVM(Java 虚拟机)的详细讲解

    #### Java运行原理概览 Java作为一种跨平台的编程语言,其核心优势在于“一次编写,到处运行”的特性。实现这一目标的关键技术是Java虚拟机(JVM)。简单来说,Java源代码在编译后会生成一种名为字节码(ByteCode)的...

Global site tag (gtag.js) - Google Analytics