Java虚拟机跨平台核心模块的实现原理
- 格式:pdf
- 大小:879.70 KB
- 文档页数:5
java虚拟机的工作原理Java虚拟机(JVM)是Java程序运行的环境,它负责解释和执行Java字节码。
JVM的工作原理可以分为三个主要的部分:类加载、字节码执行和垃圾回收。
1.类加载:JVM通过类加载器将Java字节码加载到内存中。
类加载器根据类路径在文件系统或网络中查找并读取字节码文件,然后将其转化为JVM运行时数据结构,如类和方法的元数据。
加载完成后,JVM会在方法区中存储类的元数据,并在堆中分配内存来存储类的实例。
2.字节码执行:3.垃圾回收:JVM提供垃圾回收机制来自动释放不再使用的内存。
JVM会跟踪每个对象的引用,当一个对象没有引用时,即被视为垃圾。
垃圾回收器定期执行垃圾收集操作,释放垃圾对象占用的内存。
垃圾回收器有不同的实现策略,如标记-清除、引用计数、复制、标记-整理等。
除了以上三个主要的部分,JVM还包含其他组件,如堆内存、栈、方法区等。
堆内存用于存储对象实例,栈用于存储局部变量和方法调用参数,方法区用于存储类的元数据和静态数据。
JVM的工作过程如下:1. 通过类加载器加载Java字节码。
2.解释执行或JIT编译字节码。
3.根据需要进行垃圾回收和内存管理。
4.执行程序。
JVM的优点是跨平台性、自动内存管理和高性能。
通过JVM,Java程序可以在不同的硬件和操作系统上运行,无需修改源代码。
JVM的自动内存管理功能减轻了开发人员对内存管理的负担,避免了内存泄漏和越界访问等错误。
JVM的即时编译技术能够将热点代码优化为本地机器代码,提高程序的执行效率。
在实际的Java应用开发中,了解JVM的工作原理有助于编写高效的代码和解决性能问题。
开发人员可以通过调整JVM参数、选择合适的垃圾回收器和内存分配策略来优化程序的性能。
同时,了解JVM的工作原理还有助于理解虚拟机层面的问题和调优技巧,提升应用的可靠性和稳定性。
java虚拟机运行原理Java虚拟机(Java Virtual Machine,JVM)是Java程序运行的基础,它是Java语言的核心部分。
本文将深入探讨Java虚拟机的运行原理,包括JVM的体系结构、类加载过程、内存管理、垃圾回收和即时编译等关键内容。
一、JVM的体系结构Java虚拟机的体系结构包括类加载器(ClassLoader)、运行时数据区(Runtime Data Area)和执行引擎(Execution Engine)。
类加载器负责将Java源文件编译后的字节码文件加载到JVM中,运行时数据区包括方法区、堆、虚拟机栈、本地方法栈和程序计数器,而执行引擎则负责解释和执行字节码。
二、类加载过程类加载是Java虚拟机的核心功能之一,它将类的二进制数据加载到内存中,并对数据进行校验、准备和解析。
类加载过程包括加载、验证、准备、解析和初始化五个阶段,其中验证阶段对字节码进行验证,确保它符合Java虚拟机规范;准备阶段负责为类变量分配内存,并设置初始值;解析阶段将符号引用转化为直接引用;初始化阶段是类加载过程的最后一步,它负责执行类的初始化方法。
三、内存管理Java虚拟机的内存管理主要包括堆、栈和方法区。
堆是Java虚拟机中最大的一块内存区域,用于存储对象实例和数组。
栈则用于存储局部变量、方法参数和返回值等信息,它以栈帧的形式存在,每个方法调用都会创建一个栈帧。
方法区用于存储类的结构信息、常量池和静态变量等数据。
四、垃圾回收Java虚拟机通过垃圾回收机制来自动释放不再使用的内存。
垃圾回收的核心算法包括标记-清除、复制、标记-整理和分代收集等。
标记-清除算法先标记出所有活动对象,然后清除未标记的对象;复制算法将内存分为两块,一块用于存储存活对象,另一块用于存储新创建的对象,当一块内存用完后,将活动对象复制到另一块内存中;标记-整理算法将存活对象向一端移动,然后清理掉端部空间;分代收集算法将内存划分为不同的代,根据对象的存活周期采用不同的垃圾回收算法。
jvm底层原理Java虚拟机(JVM)是一个虚拟环境,用于运行Java字节码和管理应用程序的内存。
它是Java程序模型和程序语言的基础,可以让Java程序在跨平台的操作系统中被执行和运行。
JVM的底层原理是什么呢?本文将探索JVM的底层原理以及它是如何实现跨平台运行的。
JVM的底层原理就是:将Java程序编译为字节码,然后由JVM 负责执行这些字节码,并负责管理Java程序的内存。
JVM由几部分组成:类加载器、解释器、调用处理器和运行时数据区。
首先,类加载器会加载Java源程序,将其编译为字节码,字节码会被加载到解释器中。
解释器定义了基本的Java语言规则,然后会解释、执行字节码,并将执行结果反馈给调用处理器。
调用处理器会对不同方法调用做出不同反应,这些方法调用包括内部类方法调用、虚拟方法调用等。
接下来,运行时数据区会存储程序的各种变量和对象,并且管理内存。
最后,JVM会利用垃圾回收机制来管理内存,确保程序不出现内存泄漏问题。
因此,JVM的底层原理是:将程序编译为字节码,由解释器解释执行,由调用处理器控制方法调用,由运行时数据区管理内存,然后由垃圾回收机制管理内存,最后实现跨平台的运行。
JVM的底层原理极大地改善和简化了Java程序的运行,使得Java 程序能够在不同平台上运行。
JVM的底层原理不仅提高了Java程序的执行效率,而且提供了安全的程序运行环境,确保了Java程序的稳定性。
总之,JVM的底层原理是一个重要的技术,使得Java程序能够跨平台地运行,提高了程序执行效率,提供了一个安全的运行环境。
研究JVM的底层原理,一定会帮助Java程序员实现更高效和安全的程序编写。
java工作原理Java工作原理。
Java是一种广泛应用的编程语言,它的工作原理涉及到许多方面,包括编译、虚拟机、内存管理等。
本文将从这些方面逐一介绍Java的工作原理。
首先,让我们来看看Java的编译过程。
与许多其他编程语言不同,Java是一种编译型和解释型混合的语言。
Java源代码首先会被编译成字节码,这是一种与特定平台无关的中间代码。
然后,Java虚拟机(JVM)会将字节码解释执行,或者通过即时编译器(JIT)将其编译成本地机器码。
这种编译和解释相结合的方式使得Java具有跨平台的特性,可以在不同的操作系统上运行。
接下来,让我们来了解一下Java虚拟机的工作原理。
JVM是Java程序的运行环境,它负责加载字节码并执行程序。
JVM包括类加载器、解释器、即时编译器、垃圾回收器等组件。
类加载器负责将类文件加载到内存中,并进行链接和初始化。
解释器可以逐行解释执行字节码,而即时编译器则可以将热点代码编译成本地机器码以提高性能。
垃圾回收器则负责管理内存,自动回收不再使用的对象,避免内存泄漏。
此外,Java的内存管理也是其工作原理中的重要部分。
Java使用自动内存管理机制,程序员不需要手动管理内存,这减少了内存泄漏和越界访问的风险。
Java的内存主要分为堆内存和栈内存。
堆内存用于存储对象实例和数组,而栈内存用于存储局部变量和方法调用。
垃圾回收器会定期扫描堆内存,回收不再使用的对象,从而释放内存空间。
总的来说,Java的工作原理涉及到编译、虚拟机和内存管理等多个方面。
通过深入了解Java的工作原理,我们可以更好地理解其运行机制,从而编写出高效、稳定的Java程序。
希望本文对您有所帮助,谢谢阅读!。
简述Java的运行原理及应用1. Java的运行原理Java是一种跨平台的计算机编程语言,具有高度的灵活性和可移植性。
它的运行原理主要包括以下几个方面:1.1 Java虚拟机(JVM)Java虚拟机(Java Virtual Machine,JVM)是Java语言的运行环境的一部分。
它是一个虚拟的计算机,可以在不同的硬件平台上运行,实现了Java程序的跨平台性。
JVM负责将Java字节码解释成可执行的机器码,并提供了内存管理、垃圾回收等功能。
1.2 Java字节码Java源代码经过编译器(javac)编译后,生成的是字节码(.class文件),而不是机器码。
Java字节码是一种中间代码,它可以在任何支持Java虚拟机的平台上运行。
JVM根据字节码文件进行解释执行,将其转换为机器码并执行。
1.3 类加载器Java的类加载器负责将字节码文件加载到内存中,并在Java程序运行时动态加载类文件。
类加载器使用双亲委派模型,首先将类加载请求委派给父类加载器,只有在父类加载器无法找到类文件时,才由子类加载器执行加载操作。
这种机制保证了类的加载顺序和加载结果的一致性。
1.4 垃圾回收Java的垃圾回收器(Garbage Collector)负责自动回收程序中不再使用的内存空间。
垃圾回收是JVM的一项重要功能,它可以减轻程序员的负担,提高程序的可靠性和安全性。
2. Java的应用Java作为一种功能强大、易用、跨平台的编程语言,在各个领域都有广泛的应用。
以下是Java的一些主要应用场景:2.1 Web应用开发Java语言具有丰富的Web开发框架和技术,如Java Servlet、JavaServer Pages (JSP)、JavaServer Faces(JSF)等。
通过使用这些技术,开发人员可以快速构建高性能、可靠的Web应用程序。
2.2 移动应用开发Java语言广泛应用于Android平台的移动应用开发。
Android开发使用的主要语言就是Java,通过Android SDK提供的各种API和工具,开发者可以轻松创建丰富多样的Android应用程序。
Java跨平台特性的实现原理摘要:跨平台是Java语言的重要特性,和普通高级语言源程序跨平台不同,Java语言的跨平台是指目标程序跨平台。
这种跨平台特性使Java语言成为了目前使用最为广泛的Internet应用编程语言。
本文介绍Java语言和其他高级语言在跨平台特性上的区别,以及Java语言实现跨平台特性的原理。
关键词:Java 跨平台Internet编程Java能够成为目前使用最广泛的一门Web程序设计语言,具备优秀的跨平台特性是一个重要的原因。
本人在大学本科的软件教学工作中发现,很多具备一定程序设计基础的本科学生对Java语言跨平台特性的理解还比较模糊,对Java和普通高级编程语言跨平台特性的区别的认识也不十分深刻。
本文介绍Java和普通高级语言跨平台特性的区别,阐述Java跨平台特性的实现原理。
1 Java的诞生、发展和特性20世纪中后期,计算机网络技术逐步成熟,并被应用到科学研究、航天和军工等各个领域,在此基础上出现了Internet(国际互联网)。
Internet把世界各地的不同结构的计算机网络、主机和个人计算机通过通信设施和通信协议互联起来构成国际互联网络。
20世纪90年代初,在Internet的基础上,又出现了WWW网络(万维网)。
WWW网是Internet提供的一种信息服务,它为Internet用户提供了统一的接口以访问网络上的各种信息和资源。
WWW网用统一资源定位技术(URL)实现全球信息的精确定位;用新的应用层协议(HTTP)实现分布式信息共享;用超文本技术(HTML)实现信息之间的链接。
这些技术使WWW 网用户能方便地访问到Internet上的共享信息。
随着WWW应用的快速增长,SUN公司的James Gosling等人意识到需要一种面向WWW网的程序设计语言,于是他们把一种名叫Oak的编程语言加以改造并用于Web编程(WWW网络编程),并与1995年5月23日正式更名为Java语言。
JVM运行机制及其原理JVM(Java Virtual Machine)是Java虚拟机的缩写,是运行Java 字节码的虚拟计算机。
它是Java平台的核心组件,负责在不同的操作系统上执行Java程序。
JVM运行机制主要包括类加载、字节码解释、即时编译、垃圾收集等过程,下面将详细介绍JVM运行机制及其原理。
1.类加载当一个Java程序被运行时,JVM会首先加载程序的主类,然后根据程序的依赖关系逐步加载相关的类。
类加载过程主要分为加载、验证、准备、解析和初始化几个阶段:-加载:通过类加载器将类文件加载到内存中。
- 验证:确保加载的类符合Java语言规范和JVM规范。
-准备:为类的静态变量分配内存并初始化为默认值。
-解析:将符号引用转换为直接引用。
-初始化:执行类的初始化方法。
2.字节码解释加载完类文件后,JVM会通过解释器将字节码文件逐条解释执行,将每条字节码翻译成对应的机器代码并执行。
这种方式简单直接,但效率较低,适用于少量代码和频繁切换的情况。
3.即时编译4.垃圾收集JVM还负责管理程序的内存,包括分配内存、回收无用内存等。
在Java中,内存是通过堆和栈来管理的,堆用于存放对象实例,栈用于存放基本数据类型和方法调用。
JVM通过垃圾收集器来管理堆内存,自动回收不再使用的对象,并将内存释放出来供其他对象使用。
5.类加载器类加载器是JVM的重要组成部分,负责加载class文件,并将其转换成JVM可以识别的数据结构。
JVM中存在多个类加载器,分为三个级别:启动类加载器、扩展类加载器和应用程序类加载器。
类加载器采用双亲委派模型,当需要加载一个类时,先委托给父类加载器加载,只有当父类加载器无法找到类时,才由自己加载。
6.内存模型JVM中的内存分为程序计数器、虚拟机栈、本地方法栈、堆、方法区等几部分。
程序计数器记录当前指令执行的位置;虚拟机栈用于存放局部变量表和操作数栈;本地方法栈用于支持本地方法调用;堆用于存放对象实例;方法区用于存放类信息、静态变量等。
java 底层原理
Java 是一种高级编程语言,它通过使用 Java 虚拟机(JVM)来实现跨平台的特性。
Java 底层原理是建立在字节码的基础上。
当 Java 代码编译完成后,会生成字节码文件,即以 .class 为后缀的文件。
字节码是一种中间文件,它包含了 Java 源代码编译后的指令集。
Java 虚拟机是负责解释执行字节码的运行环境。
JVM 在不同平台上的实现可能会有所不同,但其基本功能都相似。
JVM 将字节码解释成平台相关的机器码,然后通过操作系统的系统调用来执行机器码,从而实现了 Java 的跨平台性。
在运行 Java 程序时,JVM 会将字节码加载到内存中,然后对其进行解释执行。
JVM 使用即时编译器(JIT)将热点代码编译成本地机器码,以提高程序的执行性能。
同时,JVM 还负责进行垃圾回收和内存管理,以确保程序的安全性和稳定性。
Java 还提供了丰富的类库和 API,这些类库和 API 是由 Java 开发人员编写的,并通过 Java 底层原理实现了各种功能。
开发人员可以使用这些类库和 API 来简化代码的编写,提高开发效率。
总之,Java 底层原理是通过将 Java 代码编译成字节码,并通过 JVM 解释执行字节码来实现跨平台的特性。
JVM 负责将字节码加载到内存中进行解释执行,并通过即时编译器将热点代
码编译成本地机器码。
同时,Java 还提供了丰富的类库和 API,方便开发人员进行开发。
概述什么是Java虚拟化技术?Java虚拟机的基本概念Java虚拟机的工作原理Java程序的编译与执行过程JVM的基本组成和功能类加载器与字节码解释器JIT编译器和运行时优化Java虚拟化技术的应用服务器端应用移动设备应用嵌入式系统应用云计算和大数据应用Java虚拟化技术的挑战与未来性能问题与优化手段安全隐患与防范措施跨平台兼容性与标准化新兴技术的发展与应用结论Java虚拟化技术的原理与实践概述在计算机领域,Java虚拟化技术是一种通过Java虚拟机(JVM)实现的硬件和操作系统无关的编程方式。
它可以将Java程序编译成字节码,然后在不同的平台上运行。
本文将介绍Java虚拟化技术的原理和实践,深入探讨其在不同领域的应用和挑战,并展望其未来发展的方向。
Java虚拟机的工作原理Java程序的编译与执行过程在Java开发中,程序员首先使用Java编译器将Java源代码编译成字节码。
然后,这些字节码被加载到JVM中,并由JVM的解释器将其转换为机器码执行。
这种分阶段的执行方式有助于提高程序的可移植性和跨平台性。
JVM的基本组成和功能JVM由四个主要组件组成:类加载器、字节码解释器、即时编译器(JIT)和运行时数据区域。
类加载器负责加载和验证字节码文件,字节码解释器将字节码转换为机器码执行,JIT编译器则负责将热点代码编译为本地机器码以提高执行效率。
运行时数据区域包括堆、栈、方法区等,用于存储程序执行过程中的数据和运行时状态。
类加载器与字节码解释器类加载器是JVM的关键组件之一,它负责动态加载类文件并将其转换为可执行代码。
字节码解释器则负责解释和执行字节码指令。
这种分离的设计能够在运行时动态加载和执行代码,增强了程序的灵活性和可扩展性。
JIT编译器和运行时优化JIT编译器是JVM中的一个重要组件,它在运行时动态地将热点代码编译为本地机器码。
通过使用JIT编译器,Java虚拟机能够实现更高的执行效率,减少解释器的性能损失。
JVM工作原理JVM(Java Virtual Machine)是Java虚拟机的缩写,是Java程序运行的基础。
它是一个抽象的计算机,通过解释和执行Java字节码来实现Java程序的运行。
JVM的工作原理涉及到类加载、字节码解释和执行、垃圾回收等多个方面。
1. 类加载在JVM中,类的加载是指将类的字节码文件加载到内存中,并对其进行校验、准备和解析的过程。
类加载器负责将类文件加载到内存,并生成对应的Class对象。
JVM内置了三个类加载器:启动类加载器、扩展类加载器和应用程序类加载器。
启动类加载器负责加载核心类库,扩展类加载器负责加载Java的扩展类库,应用程序类加载器负责加载应用程序的类。
2. 字节码解释和执行在类加载完成后,JVM会将类的字节码文件解释成机器码,并按照一定的顺序执行。
字节码解释和执行是JVM的核心功能之一。
JVM采用解释执行的方式,通过解释器逐行解释字节码并执行相应的操作。
这种方式的好处是跨平台,但执行效率相对较低。
3. 即时编译为了提高执行效率,JVM还引入了即时编译(Just-In-Time Compilation,JIT)技术。
即时编译器可以将热点代码(被频繁执行的代码)编译成本地机器码,以提高执行速度。
JIT编译器会监测程序的执行情况,当发现某段代码被频繁执行时,就会将其编译成机器码,并替换原来的解释执行代码。
4. 内存管理和垃圾回收JVM负责管理程序运行时的内存,包括堆内存和栈内存。
堆内存用于存储对象实例,栈内存用于存储方法调用和局部变量等。
JVM通过垃圾回收机制来自动管理内存的分配和释放。
垃圾回收器会定期扫描堆内存,标记并清理不再使用的对象,释放内存空间。
5. 运行时数据区域JVM将内存划分为不同的运行时数据区域,包括方法区、堆、栈、程序计数器和本地方法栈等。
方法区用于存储类的结构信息、常量池等。
堆用于存储对象实例。
栈用于存储方法的调用和局部变量等。
程序计数器用于记录当前线程执行的字节码指令地址。
Implementation Principle of Cross-platform Core Module of Java Virtual MachineShijian FENG Zhengde BAO Yawen TANGSchool of Computer and Software,Jincheng College,Sichuan University,Chengdu,Sichuan,611731 AbstractJAV A has become popular in the field of programming because of its ing the bytecode loader in JVM,one compilation can be realized and run everywhere.This paper mainly expounds the bytecode loading engine and its implementation principle in JVM,and briefly analyses how to transform high-level language into machine language which can be recognized by machine through a series of processing,and realize cross-platform operation.Key WordsJava Virtual Machine,Bytecode,Dynamic Allocation,Stack frameDOI:10.18686/jsjxt.v1i2.648Java虚拟机跨平台核心模块的实现原理冯世建鲍正德唐娅雯四川大学锦城学院计算机与软件学院,四川,成都,611731摘要JAVA因其可移植性在编程领域热度不减。
利用JVM中的字节码加载器可以实现一处编译,到处运行。
本文主要阐述了JVM中的字节码加载引擎及实现的原理,浅析了如何将高级语言经过一系列的处理转化为机器可以识别的机器语言,并实现跨平台运行。
关键字JAVA虚拟机;字节码;动态分派;栈帧1.引言JAV A可以跨平台是因为JVM的可移植性,JVM 起到一个连接OS和JAVA源码的作用。
JAV A虚拟机可以帮助程序员完成许多难以完成的事,所以被广大程序员使用,但却很少有人了解其内部具体的实现原理。
从原理的角度对虚拟机进行剖析,确定了我们优化的方向:栈帧的复用和修改基于栈的指令集都可以达到优化虚拟机的目的。
虚拟机中的栈有着独有的特殊结构,这极大的提高了静态解析和分派的效率,为后面的解释执行做了铺垫。
2.JVM字节码执行引擎运行时的栈帧结构线程中存在的栈,在虚拟机中被叫做虚拟机栈,Java虚拟机栈一般存在于通用RAM中,程序指令在进行操作时,需要由出入栈配合来完成[1],虚拟机栈是由一个个栈帧组成的。
在虚拟机堆栈中,虚拟机栈被分配到每一个线程中,栈中包含一定的栈帧。
每个栈帧都包含方法,动态连接,操作数栈,局部变量表和方法返回地址信息等。
在活动的线程中,每次调用方法是都伴随着栈帧的入栈与出栈,栈帧是从栈顶开始出栈的,出栈栈帧被叫做有效栈帧。
同时值得注意的是栈中的栈帧有数量限制,所以尽量避免过多的方法调用导致内存的溢出。
2.1栈帧的数据结构在栈帧中,变量槽是最小的单位,包含32个字节。
在32位的虚拟机中,一个变量槽代表32位,同理在64位的虚拟机中两个变量槽代表64位。
如果在64位的虚拟机中模拟32位的填充,可以通过补码。
在代码编译的过程中,栈帧所需要的大小就已经被计算出来了。
所以,在运行的时候,栈帧所需的内存大小不会被其他变量所影响。
2.2局部变量表栈帧中有局部变量表,局部变量表储存了已经写好的方法和这个方法所需要的参数信息。
这个表的基本单位是上文提到的变量槽。
虚拟机查询这个表需要用到索引。
在32位的变量中,通过索引k可以查找到第k个变量槽;而在64位的变量中第k个索引占用了k和k+1这两个变量槽。
在64位的虚拟机中,两个变量槽是同时被访问的,不可拆分,如果遇到了单独访问的情况,需要抛出一个异常。
在栈帧中,重用变量槽可以带来性能的提升,但这可能会导致GC没有及时回收垃圾。
做一个实验,如果我们在一个类中执行栈帧中的对象,并在对象后面调用GC,这时候并没有触发GC的回收,这是因为这个对象处于被使用的状态,生命周期还没有结束:byte[]dataType=new byte[24*1024];System.gc();但是如果我们把这个对象放在普通代码块中,并在这个代码块执行完毕之后调用GC,这个对象的生命周期已然结束,可是依旧没有引发GC的回收。
{byte[]dataType=new byte[24*1024];}System.gc();而以下代码会引发GC的回收:{byte[]dataType=new byte[24*1024];}int temp=0;System.gc();通过这个实验证明:只有当使用公用变量槽的方法时置空不用的对象,才会引发GC的回收。
这里使用到了Java高效编程的思想,随时置空不使用的对象。
2.3操作数栈操作数栈中的元素是后入先出的。
他和上文的局部变量表一样在编译期间就确定了大小,其中可以存放JAVA中的所有类型的数据。
当栈帧中的方法被执行时,方法中的操作栈会伴随一系列的出栈和入栈。
可使用字节码指令可以将内容压入到这个操作栈中,这是pop/push操作。
操作栈可以运行一般的计算方程式,当调用计算的方法时,算术符号被当做参数圧栈。
例如,执行一个简单的加法运算,通过iadd指令可以将操作栈中最后进来的元素依次取出,并进行相加。
执行此指令时,将弹出并添加两个数值,并将添加的结构压栈。
值得注意的是,指令应在适当的范围内使用,iadd指令用于整数加法,其他类型的数据类型相加的话就会抛出异常。
有序虚拟机栈中的栈帧是互不相干的独立个体,所以我们可以想到通过栈帧的重叠来优化数据结构,得到数据的重用。
2.4动态链接通过把程序分离,可以达到更好的空间利用的目的,同时栈帧中的元素也可以被动态的更改了。
字节码中,存在许多符号引用,这些符号引用被当做参数被方法调用指令所调用,当含有这个符号引用的时候便可以实现动态链接动态的调用这个引用。
在类开始加载的时候(解析)或首次使用时,符号引用会直接转换为直接引用,这个过程就叫做静态链接。
如果一些符号引用在运行期被转换为直接引用,就被叫做动态链接。
所以虚拟机可以直接将这些符号引用链接起来运行,而不用去寻找一个个文件,等程序运行起来的时候可以动态的将他们链接在一起,就达到了程序模块分离的效果。
3.JVM字节码执行引擎运行时的方法调用3.1解析3.1.1解析调用通过一个Class文件我们可以得到程序中的所有类,接口和方法的信息[2]。
在常量池中,符号引用还包括调用的方法所指的目标方法。
也就是说,方法会在编译阶段被明确调用,这个方法的调用就是解析调用,这是一个非动态的过程。
3.1.2适合在编译期解析的方法JAVA中的静态方法和私有方法在运行期间是不能改变的,因此他们可以在编译期间被确定。
私有方法不能在类的外部被访问,静态方法与类型直接关联,所以不可以重写,所以它们往往在类开始加载的时候被解析。
方法的调用主要是为了确定在运行期调用哪个方法,并不会真正的运行,所以这个过程是静态的。
这种特殊的链接方式极大地提高了Java的可变性和可扩展性,但却增加了复杂度。
3.1.3字节码的调用方法在字节码中,常量池中调用非虚方法的方式主要有两种:调用静态方法invokestatic(静态绑定,速度快),调用虚方法invokevirtual(实例方法)[3]。
下面我们将在静态解析中演示非虚方法的调用:public class Calling{public static void callingMethod(){System.out.println(“This method has been called”);}public static void main(String[]args){Calling.callingMethod();}}运行这段代码之后,我们在目录中找到生成的class 文件,使用javap观察其中的内容:public static void callingMethod();descriptor:()VCode:0:getstatic#2// Fieldjava/lang/System.out:Ljava/io/PrintStream;3:ldc#3//String This method has been called5:invokevirtual#4//Method java/io/PrintStream.println:(Ljava/lang/String;)V8:return经过实验证明invokestatic确实调用了callingMethod方法。
3.2JVM实现分派除了静态的解析,分派是在另外一个层次的目标方法筛选。
由于JAVA中特殊的动态分配,提出了虚方法表的方法对字节码中的方法就行高效率的分配。
JVM 分派的最终目的是确定执行时方法的执行顺序,这也体现了JAVA的多态性。
3.2.1分派的原理静态过程叫做解析,而分派则可能是一个动态的过程也可能是一个静态的过程。
值得注意的是:静态本机编译器不支持Java的动态加载功能,而动态本机编译器支持Java[4]。
因此,在不影响JVM移植性的条件下,JAVA在运行时才进行对本地代码的编译,而不是在运行之前进行编译。
3.2.2JAV A的动态编译java的动态分配可以很好的处理方法的调用,考虑到使用的频繁,在这里可以想到对虚拟机性能的一些优化。
如果每一次的动态分配都去搜索元数据的话会影响代码的执行效率。
所以,JVM在类的方法区域中构建虚拟方法表以提高性能。
每个类都有一个用于保存每个方法的实际条目的虚方法表,这大大减少了搜索的次数,但同时也会牺牲一点点空间。
考虑到复用的问题,当我们写了一个子类重写了虚方法表中的这个方法的话,得到的结果是这个方法的地址原来父类的地址是相同的。
这就证明了,子类的方法指向了原来父类中的方法。
这便是重写在JAVA中的一个体现。
3.2.3动态编译的实验用一个实验来证明:准备两个静态类型相同的类A,B并继承同一个父类C,并重写C的同一个方法class Assignment{static abstract class C{protected abstract void printMethod();}static class A extends C{protected void printMethod(){System.out.print("A");}}static class B extends C{protected void printMethod(){System.out.print("B");}}public static void main(String[]args){C a=new A();C b=new B();a.printMethod();b.printMethod();a=new B();a.printMethod();}}得到的结果是:ABB。