一个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虚拟机学习java虚拟机学习java虚拟机学习java虚拟机学习
本书是继《深入理解Java虚拟机》之后的又一经典著作,它一方面遵循《Java虚拟机规范》,一方面又独辟蹊径,不仅能让Java虚拟机的学习变得更加简单和有趣,而且能让你对Java虚拟机的原理认识更深入和更深刻!...
Java虚拟机资料.zip,这是一份比较不错的Java虚拟机资料,讲的比较详细,希望可以帮助学习java虚拟机的人
本书是继《深入理解Java虚拟机》之后的又一经典著作,它一方面遵循《Java虚拟机规范》,一方面又独辟蹊径,不仅能让Java虚拟机的学习变得更加简单和有趣,而且能让你对Java虚拟机的原理认识更深入和更深刻!...
这是对学习Java虚拟机的很好的入门书。虚拟机的书很少,除了规范之外,就很少见了。
公司技术团队培训:深入学习java虚拟机
深入理解Java虚拟机学习资料 pdf+mobi
这是一个简单的Java虚拟机实现,用C++写的。可以为它编写和运行简单的java程序。这个程序是写给初学者学习用的,当然它还不完善,指令也还没有完全实现。只希望它对于初学者学习Java虚拟机有所帮助。
介绍的内容不局限于一个版本的。从8到11都会涉及到。极客时间 | 深入拆解 Java 虚拟机浮生老莫3期待老师后续的内容,刚想学JVM,就来了,再打磨打磨自己的
Java虚拟机规范(Java_SE_7)中文版,帮助很多爱好java虚拟机的同学深入学习java虚拟机
20Java虚拟机-高性能Java虚拟机.avi 3.8MB 19Java虚拟机-MicrosoftJVM.avi 4.9MB 18Java虚拟机-dalvik.avi 2.9MB 17Java虚拟机-j9.avi 5.5MB 16Java虚拟机-JRockit.avi 5.8MB 15Java虚拟机-kvm.avi 3.8MB 14...
《Java核心技术系列:Java虚拟机规范(Java SE 8版)》由Oracle官方发布,Java虚拟机技术创建人撰写,国内资深Java技术专家翻译。书中基于全新Java SE 8,完整且准确地阐述Java虚拟机规范,是深度了解Java虚拟机和...
这里我们使用举例来说明为什么要学习Java虚拟机,其实这个问题就和为什么要学习数据结构和算法是一个道理,工欲善其事,必先利其器。曾经的我经常害怕处理内存溢出的问题,因为不知道他为什么会出现这个问题,当我在...
非常详细的,非常经典的java虚拟机技术介绍,想要在Java上有所精进和深入一定要学,让我们一起成为大牛吧。
深入JAVA虚拟机,帮助大家在Java方面进行学习,深入JAVA虚拟机,帮助大家在Java方面进行学习,
学习JAVA首先要理解的JAVA虚拟机 要更快的掌握JAVA,也是要了解JAVA虚拟机 对于Java虚拟机的软件人员,Java语言的编译器作者以及要用硬件芯片实现J ava虚拟机的人来说,则必须深刻理解Java虚拟机的规范。另外,如果你想...
, 本书是继《深入理解Java虚拟机》之后的又一经典著作,它一方面遵循《Java虚拟机规范》,一方面又独辟蹊径,不仅能让Java虚拟机的学习变得更加简单和有趣,而且能让你对Java虚拟机的原理认识更深入和更深刻!...
Java虚拟机规范中文版 学习java必读,了解底层的编辑过程,学习java虚拟机规范
比较全面学习笔记文档,初学Java虚拟机建议下来看看
理解Java虚拟机的很好的书 光盘的内容是不可缺少的学习资料