上篇文章讲到了Heap(堆)相关的内容,下面紧接着讲讲Runtime Data Areas(运行数据区)中Java Stacks、PC Register、Native Method Stacks.
Java Stacks
每当启动一个新线程时,Java虚拟机都会为它分配一个Java栈。前面我们曾经提到,Java栈出帧为单位保存线程的运行状态。虚拟机只会直接对Java栈执行两种操作:以帧为单位的压栈或出栈。
某个线程正在执行的方法被称为该线程的当前方法,当前方法使用的栈帧称为当前帧,当前方法所属的类称为当前类,当前类的常量池称为当前常量池。在线程执行一个方法时,他会跟踪当前类和当前常量池。此外当虚拟机遇到栈内操作指令时,他对当前帧内数据执行操作。
每当线程调用一个Java方法时,虚拟机都会在该线程的Java栈中压入一个新帧。而这个新帧自然就成为了当前帧。在执行这个方法时,他使用这个帧来存数参数、局部变量、中间运算结果等等数据。
Java方法可以以两种方式完成。一种通过return返回的,称为正常返回;一种是通过抛出异常而异常终止的。不管哪种方式返回,虚拟机都会将当前帧弹出Java栈然后释放掉,这样上一个方法的真就成为当前帧了。
Java栈上的所有数据都是此线程私有的。任何线程都不能访问另外一个线程的栈数据,因此我们不需要考虑多线程情况下栈数据的访问同步问题。当一个线程调用一个方法时,方法的局部变量保存在调用线程Java栈的帧中。只有一个线程能总是访问那些局部变量,即调用方法的线程。
像方法区和堆一样,Java栈和帧在内存中也不是连续的。帧可以分布在连续的栈里,也可以分步在堆里,或者二者兼而有之。表示Java栈和栈帧的实际数据结构由虚拟机的实现者决定,某些实现允许用户指定Java栈的初始大小和最大最小值。
栈帧由三部分组成:局部变量区、操作数栈和帧数据区(保存一些数据来支持常量池解析、正常方法返回以及异常派发机制)
上图摘自http://rednaxelafx.iteye.com/blog/656951
PC Register
对于一个运行中的Java程序而言,其中的每一个线程都有他自己的PC(程序计数器)寄存器,它是在该线程启动时创建的。PC寄存器的大小是一个字长,因此他既能够持有一个本地指针,也能够持有一个returnAddress。当线程执行某个Java方法时,PC寄存器的内容总是下一条将被执行指令的"地址",这里的“地址”可以是一个本地指针,也可以是在方法字节码中相对于该方法起始指令的偏移量。如果该线程正在执行一个本地方法,那么此时PC寄存器的值是“undefined”。
Native Method Stacks
前面提到的所有运行时数据区都是Java虚拟机规范中明确定义的,除此之外,对已一个运行中的Java程序而言,他还可能会用到一些本地方法相关的数据区。当某个线程调用一个本地方法时,他就进入了一个全新的并且不再受虚拟机限制的世界,本地方法可以通过本地方法接口来访问虚拟机得运行时数据区,但不止于此,他还可以做任何他想做的事情。比如,他甚至可以直接使用本地处理器中的寄存器,或者直接从本地内存的堆中分配任意数量的内存等等。宗旨,他和虚拟机拥有同样的权限(或者说能力)。,
本地方法本质上是依赖于实现的,虚拟机实现的设计者可以自由地决定使用怎样的机制来让Java程序调用本地方法。
任何本地方法接口都会使用某种本地方法栈。当线程调用Java方法时,虚拟机会创建一个新的栈帧并压入java栈。然而当他调用的是本地方法时,虚拟机会保持Java栈不变,不再在线程的java栈中压入新的帧,虚拟机只是简单地动态连接并直接调用指定的本地方法。可以把这看做是虚拟机利用本地方法来动态扩展自己。就如同Java虚拟机的实现在按照其中运行的Java程序的吩咐,调用属于虚拟机内部的另一个(动态连接的)方法。
如果某个虚拟机实现的本地方法接口是使用C连接模型的话,那个他的本地方法栈就是C栈。我们知道,当C程序调用一个C函数时,其栈操作都是确定的。传递给该函数的参数已某个确定的顺序压入栈,他的返回值也以确定的方式传回调用者。同样,这就是改虚拟机实现中本地方法栈的行为。
很可能本地方法接口需要回调Java虚拟机中的Java方法(这也是由设计者决定的),在这种情形下,该线程会保存本地方法栈的状态并进入到另一个Java栈。
下图描绘了这种情况,就是当一个线程调用一个本地方法时,本地方法又回调虚拟机中的另一个Java方法。这幅图展示了java虚拟机内部线程运行的全景图。一个线程可能在整个生命周期中都执行Java方法,操作他的Java栈;或者他可能毫无障碍地在Java栈和本地方法栈之间跳转。
上图所示,改线程首先调用了两个Java方法,而第二个Java方法又调用了一个本地方法,这样导致虚拟机使用了一个本地方法栈。图中的本地方法栈显示为一个连续的内存空间。假设这是一个C语言栈,期间有两个C函数,他们都以包围在虚线中的灰色块表示。第一个C函数被第二个Java方法当做本地方法调用,而这个C函数又调用了第二个C函数。之后第二个C函数被第二个Java方法当做本地方法调用,而这个C函数又调用了第二个C函数。之后第二个C函数又通过本地方法接口回调了一个Java方法(第三个Java方法)。最终这个Java方法又调用了一个Java方法(他成为图中的当前方法)。
就像其他运行时内存区一样,本地方法栈占用的内存区也不必是固定大小的,他可以根据需要动态扩展或者收缩。某些是实现也允许用户或者程序员指定该内存区的厨师大小以及最大最小值。
至此运行数据区的内容就已经介绍完了。
- 大小: 49.9 KB
- 大小: 29.6 KB
分享到:
相关推荐
总的来说,《自己动手写Java虚拟机(GO语言)》是一本结合理论与实践的优秀教材,适合对JVM感兴趣的开发者,尤其是那些希望深入理解Java平台内部运作的Go语言爱好者。通过阅读和实践,读者将能够更全面地掌握JVM的...
《自己动手写Java虚拟机》是Java核心技术系列中的一本书,旨在帮助读者深入理解Java虚拟机(JVM)的工作原理,以及如何从零开始构建一个简单的JVM。这本书通过实践的方式,让读者能够亲手实现虚拟机的关键功能,从而...
总之,《自己动手写Java虚拟机》这本书提供了一条深入学习JVM的实践之路,通过对JVM的构造和运作过程的亲身体验,读者能够更深入地理解Java平台的底层机制,这对于成为一名优秀的Java开发者或系统优化专家具有极大的...
《自己动手写Java虚拟机》是一本面向技术爱好者和Java开发者深入理解JVM原理的书籍。这个项目旨在挑战自我,通过实践来理解Java虚拟机的工作机制,从而更好地优化代码、提高程序性能。对于想要深入Java平台的人来说...
《自己动手写虚拟机》是一本深度探讨Java虚拟机(JVM)原理和技术的书籍,主要面向对计算机底层运行机制有浓厚兴趣的开发者和学生。通过亲手构建虚拟机,读者可以深入理解Java程序是如何被解释执行的,以及JVM如何...
Java虚拟机非常复杂,要想真正理解它的工作原理,最好的方式就是自己动手编写一个! 本书是继《深入理解Java虚拟机》之后的又一经典著作,它一方面遵循《Java虚拟机规范》,一方面又独辟蹊径,不仅能让Java虚拟机的...
《自己动手写Java虚拟机及class文件解析分析工具(java8运行)》是一份深入探讨Java虚拟机(JVM)工作原理以及如何解析与分析Java类文件(.class)的资源。通过使用Go语言实现一个简化的JVM,这份资料旨在帮助读者...
3. **字节码执行**:JVM通过解释器逐条执行字节码,为了提高性能,现代JVM引入了JIT编译器,它会将热点代码编译为机器码,以达到更快的执行速度。 4. **垃圾收集**:JVM的自动内存管理主要是通过垃圾收集来实现的。...
通过亲自动手构建一个简化的虚拟机,你可以学习到许多关于Java执行环境的关键知识点。以下是一些核心概念和相关知识的详细说明: 1. **Java虚拟机**:JVM是Java平台的核心组件,它为Java应用程序提供了一个运行环境...
在这个名为"JV-jvm_practice.zip"的压缩包中,你将找到一系列关于JVM相关的代码示例,帮助你深入理解JVM的工作原理。以下是对这些关键知识点的详细解释: 1. **类加载机制**: Java的类加载机制分为加载、验证、...
Java虚拟机非常复杂,要想真正理解它的工作原理,最好的方式就是自己动手编写一个!, 本书是继《深入理解Java虚拟机》之后的又一经典著作,它一方面遵循《Java虚拟机规范》,一方面又独辟蹊径,不仅能让Java虚拟机的...
Java虚拟机非常复杂,要想真正理解它的工作原理,最好的方式就是自己动手编写一个! 本书是继《深入理解Java虚拟机》之后的又一经典著作,它一方面遵循《Java虚拟机规范》,一方面又独辟蹊径,不仅能让Java虚拟机的...
7. **自己动手写Java虚拟机**:`自己动手写Java虚拟机 (Java核心技术系列.pdf`提供了一种实践性的学习方法,通过构建自己的JVM,从底层理解Java的运行机制。 8. **Effective Java**:`effective-java-2.pdf`是Java...
3. **JVM** - 类加载机制:理解双亲委派模型,探讨类加载过程。 - 垃圾回收:分析垃圾回收机制,如GC算法、垃圾收集器和内存分代模型。 - 调优:学习如何通过JVM参数调整内存分配,优化性能。 - 类加载器:了解...
通过这些示例,你可以亲自动手运行代码,加深对理论知识的理解,体验实际编程过程中的问题和解决方案。每个示例都是精心设计的,旨在帮助你更好地掌握Java核心技术,并能将其应用到实际项目中。 总的来说,这个...