一个Java虚拟机实例的职责就是负责运行一个Java程序,当通过main启动一个Java程序时,一个虚拟机实例就诞生了。如果同时运行三个Java程序,将得到三个Java虚拟机实例。例子:tomcat启动之后就只有一个Java虚拟机实例。
当Java虚拟机运行一个程序时需要内存来存储很多东西,例如,字节码,从已装载的class文件中得到的信息,对象实例,方法参数,返回值,局部变量以及中间结果等等,Java虚拟机把这些东东组织到几个“运行时数据区”中,便于管理。如下图所示:
方法区:
在方法区中主要保存如下信息:
1)、类型的全名
2)、类型的父类型的全名
3)、给类型是一个类还是接口
4)、类型的修饰符
5)、所有父接口全名的列表
类型全名保存的数据结构由虚拟机实现者定义。除此之外,Java虚拟机还要为每个类型保存如下信息:
1)、类型的常量池
2)、类型字段的信息
3)、类型方法的信息
4)、所有的静态类变量(非常量)信息
5)、一个指向类加载器的引用
6)、一个指向Class类的引用
重点说下常量池,常量池中除了存储直接常量(final常量、字符串)外,还存储类,字段和方法的符号引用。常量池解析指的就是把这些符号引用替换为相应的指针。
堆:
Java程序在运行时创建的所有类实例或数组都放在同一个堆中。而一个Java虚拟机实例中只存在一个堆空间,因此所有线程都共享这个堆。因此对于多个线程访问这个堆中的同一实例(单例)时需要考虑线程同步问题,多例不用考虑线程同步。
举个例子:在web开发中,通过main方法启动tomcat后就启动了一个Java虚拟机实例,且此后一直仅有这个虚拟机实例,因此也就只存在一个堆空间,所有线程都共享这个堆。而每个用户通过浏览器发送请求访问服务器上的Action时就启动了一个线程,对于struts1.x而言,Action为单例,即每个线程访问的Action都是堆中的同一个类实例,需要考虑线程同步。而对于struts2.x而言,Action为多例,即每个线程访问的Action都是不同的类实例,不需要考虑线程同步。
堆中都存了些什么东东?堆中存储的Java类实例由它所属的类及其超类的实例变量组成。另外这个类实例必须能够找到自己相应的类数据(存储在方法区中),因此在类实例中还应该存储一个指向方法区类数据的指针(否则你光有数据,没有方法信息,怎么执行?)。下面的两张可能的堆空间设计图,其中都包含了方法区的指针(ptr to class data)。
PC寄存器:
每一个线程都有它自己的PC寄存器,也是该线程启动时创建的。PC寄存器的内容总是指向下一条将被执行指令的地址,这里的地址可以是一个本地指针,也可以是在方法区中相对应于该方法起始指令的偏移量。
Java栈:
每一个线程都有它自己的Java栈,栈中可以存储方法参数,返回值,局部变量以及中间结果等等。
每个线程都有自己的pc寄存器(程序计数器)和java栈,如果线程正在执行一个方法,pc寄存器的值总是指向下一条将被执行的指令。
Java栈是由许多栈帧组成的,一个栈帧包含一个Java方法调用的状态。当线程调用一个Java方法时,虚拟机压入一个新的栈帧到该线程的Java栈中,当该方法返回时,这个栈帧被从Java栈中弹出并抛弃。
栈帧由3部分组成:局部变量区、操作数栈和帧数据区。
局部变量区:用于存储方法参数,返回值,局部变量以及中间结果。
操作数栈:用于存储操作数。它执行标准的栈操作:进栈、出栈。如果某个指令把一个值压入到操作数栈中,稍后另一个指令就可以弹出这个值来使用。
看一个例子:
void add() {
int m = 4;
int n = 5;
int l = m + n;
}
上面的这个方法对应的指令操作如下(注释是我添加的):
0: iconst_4 //将int型4推送至操作数栈顶
1: istore_1 //将栈顶int型数值存入第2个局部变量
2: iconst_5 //将int型5推送至操作数栈顶
3: istore_2 //将栈顶int型数值存入第3个局部变量
4: iload_1 //将第2个int型局部变量推送至操作数栈顶
5: iload_2 //将第3个int型局部变量推送至操作数栈顶
6: iadd //将操作数栈顶两int型数值相加并将结果压入栈顶
7: istore_3 //将栈顶int型数值(相加结果)存入第4个局部变量
8: return //从当前方法返回,此方法对应的帧栈被从java栈中弹出并抛弃
本地方法栈:
本地方法栈用于支持native方法的执行,存储了native方法的调用状态。
- 大小: 18.3 KB
- 大小: 45.4 KB
- 大小: 35.8 KB
- 大小: 9.4 KB
分享到:
相关推荐
在本文中,我们将深入探讨为何学习Java虚拟机对于Java程序员至关重要。 首先,理解JVM的工作原理可以帮助我们提升程序的性能。JVM提供了大量的可配置参数,这些参数可以微调以适应不同的应用场景,优化程序的启动...
学习Java虚拟机对于深入理解Java程序的执行机制至关重要。这里我们将深入探讨Java虚拟机的几个关键知识点。 1. 类加载机制:Java程序的执行始于类加载。JVM有三个主要的类加载器——bootstrap classloader、...
本书是继《深入理解Java虚拟机》之后的又一经典著作,它一方面遵循《Java虚拟机规范》,一方面又独辟蹊径,不仅能让Java虚拟机的学习变得更加简单和有趣,而且能让你对Java虚拟机的原理认识更深入和更深刻!...
Java虚拟机(JVM)是Java编程语言的核心组成部分,它是一种抽象的计算设备,能够运行Java字节码。Java虚拟机规范(Java SE 7版)是定义JVM行为的官方文档,确保所有Java平台的实现遵循相同的规则,以提供跨平台的...
Java虚拟机(JVM)是Java程序运行的基础,它负责执行Java字节码,提供了一个与平台无关的执行环境。JVM规范定义了JVM的结构、指令集和运行时数据区,以及如何执行指令和处理异常。自1999年以来,JVM规范经历了多次...
Java虚拟机(JVM)是实现Java技术的关键组件,它为Java程序提供了一个运行环境。Java程序在编写后会被编译成一种称为字节码的中间表示形式,这种字节码可以跨平台运行,因为JVM负责将字节码转换成机器代码。JVM的...
中文版的《Java虚拟机规范》填补了国内关于JVM领域知识的空白,使得中国广大对JVM感兴趣的程序员能够克服语言障碍,深入学习和掌握这一关键技术。译者们在翻译过程中,注重保持作品的准确性与可读性,尽可能采用通俗...
《Java虚拟机规范》不仅是学习Java虚拟机的基础,也是深入理解Java语言的关键。无论是初学者还是经验丰富的开发者,都可以从中获益匪浅。尽管随着技术的发展,高性能虚拟机的实际实现方式可能与规范描述的内容有所...
本书是继《深入理解Java虚拟机》之后的又一经典著作,它一方面遵循《Java虚拟机规范》,一方面又独辟蹊径,不仅能让Java虚拟机的学习变得更加简单和有趣,而且能让你对Java虚拟机的原理认识更深入和更深刻!...
通过深入学习《Java虚拟机(第二版)》,开发者不仅可以理解Java程序的运行机制,还能掌握性能优化、问题排查等高级技巧,提升自己的编程水平。这本书通常会详细讲解上述知识点,并提供丰富的示例和实践指导,帮助...
深入学习java虚拟机 Java虚拟机(JVM)是Java语言的核心组件之一,负责将Java字节码转换为机器码并执行。在Java应用程序中,JVM扮演着至关重要的角色,它管理着Java程序的生命周期,包括类加载、内存分配、垃圾回收...
这是对学习Java虚拟机的很好的入门书。虚拟机的书很少,除了规范之外,就很少见了。