`
longxiaoyan
  • 浏览: 77308 次
  • 性别: Icon_minigender_1
  • 来自: 桂-京
社区版块
存档分类
最新评论

学习Java虚拟机

    博客分类:
  • JVM
 
阅读更多
一个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
2
2
分享到:
评论
2 楼 Just_抱怨 2011-10-13  
顶下,我对基础知识掌握的不好,知道有这么和东东,但不知道是干嘛的,怎么干的
1 楼 zhufeng1981 2011-10-12  
“虚拟机实例”——理解的不错。

相关推荐

    00开篇词 为什么我们要学习Java虚拟机?1

    在本文中,我们将深入探讨为何学习Java虚拟机对于Java程序员至关重要。 首先,理解JVM的工作原理可以帮助我们提升程序的性能。JVM提供了大量的可配置参数,这些参数可以微调以适应不同的应用场景,优化程序的启动...

    java虚拟机学习

    学习Java虚拟机对于深入理解Java程序的执行机制至关重要。这里我们将深入探讨Java虚拟机的几个关键知识点。 1. 类加载机制:Java程序的执行始于类加载。JVM有三个主要的类加载器——bootstrap classloader、...

    自己动手写Java虚拟机 (Java核心技术系列)@

    本书是继《深入理解Java虚拟机》之后的又一经典著作,它一方面遵循《Java虚拟机规范》,一方面又独辟蹊径,不仅能让Java虚拟机的学习变得更加简单和有趣,而且能让你对Java虚拟机的原理认识更深入和更深刻!...

    Java虚拟机规范中文版(JavaSE7).pdf

    Java虚拟机(JVM)是Java编程语言的核心组成部分,它是一种抽象的计算设备,能够运行Java字节码。Java虚拟机规范(Java SE 7版)是定义JVM行为的官方文档,确保所有Java平台的实现遵循相同的规则,以提供跨平台的...

    Java虚拟机规范 JavaSE7

    Java虚拟机(JVM)是Java程序运行的基础,它负责执行Java字节码,提供了一个与平台无关的执行环境。JVM规范定义了JVM的结构、指令集和运行时数据区,以及如何执行指令和处理异常。自1999年以来,JVM规范经历了多次...

    Java虚拟机规范中文版.pdf

    Java虚拟机(JVM)是实现Java技术的关键组件,它为Java程序提供了一个运行环境。Java程序在编写后会被编译成一种称为字节码的中间表示形式,这种字节码可以跨平台运行,因为JVM负责将字节码转换成机器代码。JVM的...

    Java虚拟机规范(中文版).pdf

    中文版的《Java虚拟机规范》填补了国内关于JVM领域知识的空白,使得中国广大对JVM感兴趣的程序员能够克服语言障碍,深入学习和掌握这一关键技术。译者们在翻译过程中,注重保持作品的准确性与可读性,尽可能采用通俗...

    Java虚拟机规范

    《Java虚拟机规范》不仅是学习Java虚拟机的基础,也是深入理解Java语言的关键。无论是初学者还是经验丰富的开发者,都可以从中获益匪浅。尽管随着技术的发展,高性能虚拟机的实际实现方式可能与规范描述的内容有所...

    自己动手写Java虚拟机 kindle 版本

    本书是继《深入理解Java虚拟机》之后的又一经典著作,它一方面遵循《Java虚拟机规范》,一方面又独辟蹊径,不仅能让Java虚拟机的学习变得更加简单和有趣,而且能让你对Java虚拟机的原理认识更深入和更深刻!...

    java虚拟机

    通过深入学习《Java虚拟机(第二版)》,开发者不仅可以理解Java程序的运行机制,还能掌握性能优化、问题排查等高级技巧,提升自己的编程水平。这本书通常会详细讲解上述知识点,并提供丰富的示例和实践指导,帮助...

    深入学习java虚拟机.pptx

    深入学习java虚拟机 Java虚拟机(JVM)是Java语言的核心组件之一,负责将Java字节码转换为机器码并执行。在Java应用程序中,JVM扮演着至关重要的角色,它管理着Java程序的生命周期,包括类加载、内存分配、垃圾回收...

    深入Java虚拟机-周志明

    这是对学习Java虚拟机的很好的入门书。虚拟机的书很少,除了规范之外,就很少见了。

Global site tag (gtag.js) - Google Analytics