`
glutinit
  • 浏览: 46873 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

JVM摘要--指令集介绍03

    博客分类:
  • JVM
阅读更多
    【题外话】只要学过编译原理,计算机组成类似的课程的,就不会觉得JVM的字节码太难理解。有兴趣的人,只要边看书,边写几个例子后,再javap一下慢慢看几个就大概心里有数了,其实学习JVM的东西,主要是为了让自己对它的运行方式多一些了解,在实际编程过程中心里有个概念,有些特性的底层实现心里有数就行。
   
    毕竟在大多数编程中,JVM的知识不会直接的影响到你的编程思路,但会潜移默化的让你绕过一些潜在的风险或者障碍。


    下面稍微介绍两个概念:接收参数方法调用
   

接收参数
实例方法(非静态方法)和类方法(静态方法)的实现是略有不同的,因为当调用一个实例方法时,首先会将该类的自身的实例的引用作为第0个参数放置在局部变量表中,然后才在局部变量表的第1到N的位置上放置参数(如果有参数, N是参数个数)。

       而静态方法不需要传递自身实例的应用,所以参数是从第0个开始存放。

      (要注意long和double所占局部变量的大小为2)

       大家可以用下面这两个例子做下测试
//example_1
        
int addTwo(int i, int j) { 
            return i + j; 
         }



         //example_2, static method
        
static  int addTwo(int i, int j)
         {
	         return i + j;
         }



方法调用

   对普通实例方法(即非静态方法)调用是在运行时根据对象类型进行分派的(相当于在C++中所说的“虚方法”), 这类方法通过调用invokevirtual指令实现。

   下面看一个简单的例子,然后是其字节码:
    
public class JVM_3_addTwo {
	int addTwo(int i, int j)
	{
		return i + j; 
	}
	
	int add12And13(){
		return addTwo(12, 13);
	}
     }



  
...   
int addTwo(int, int);
  Code:
   0:   iload_1
   1:   iload_2
   2:   iadd
   3:   ireturn

int add12And13();
  Code:
   0:   aload_0
   1:   bipush  12
   3:   bipush  13
   5:   invokevirtual   #2; //Method addTwo:(II)I
   8:   ireturn

}


其具体流程如下(图只是用来参考,并不一定完全正确...)

STEP1:
  从局部变量表load当前类实例的指针,将其push到操作数栈
 

STEP2:

  将常量12和13分别push到操作数栈
 

STEP3:
  调用addTwo方法,在调用该方法时,JVM创建一个新的frame,并将自己实例的指针,以及参数12和13传给新的Frame中的局部变量表。


   注:每条invokevirtual指令都会带有一个表示索引的参数,如图中的#2, 通过该标识,JVM可以通过查找常量池找到方法addTwo的符号引用,该符号引用可以提供方法所在对象的类型的内部二进制名称、方法名称和方法描述符

 


STEP4:
  目前的操作都针对Frame_addTwo中的操作数栈,如图,从局部变量表加载位置的变量和位置2的变量,即12和13

 


STEP5:
  求和运算,将结果25压入到操作数栈中

 


STEP6:
  addTwo()方法返回,将其栈顶的值(即25)push到其调用者(即add12And13)方法所在的操作数栈,并且在该调用完成后,addTwo所拥有的frame就被删除掉。


 


STEP7:
  add12And13()方法返回,将其栈顶的值(即25)push到其调用者所在的操作数栈,并且在该调用完成后,add12And13所拥有的frame就被删除掉。

 



0
1
分享到:
评论

相关推荐

    The Java Virtual Machine Specification, Java SE 7 Edition

    文档提供了一个指令集摘要,详细介绍了不同类型的指令,如加载/存储指令、算术指令、类型转换指令、对象创建与操作指令、操作数栈管理指令、控制转移指令、方法调用与返回指令以及抛出异常指令等。 10. Special ...

    一种实时Java处理器的指令存取部件设计与实现.pdf

    由于Java虚拟机(JVM)基于堆栈的实现方式,处理器的存储体系结构与传统的RISC(精简指令集计算)处理器有所不同。文章提出了一种针对实时Java处理器的指令预取方案,该方案很好地适应了Java特有的体系结构。 ...

    Java虚拟机规范

    5. 指令集:JVM使用字节码作为中间语言,如`aload_0`表示加载局部变量表的第一个引用类型变量。字节码通过解释器或即时编译器(JIT)转化为机器码执行。 6. 内存管理:Java的内存管理主要包括自动垃圾收集,采用...

    Java虚拟机规范(英文)

    6. 规范的作用:JVM规范作为Java平台的基础性文档,规定了JVM的内部架构、数据类型、指令集、运行时数据区、垃圾收集机制等核心内容,是Java开发者和虚拟机实现者必须遵循的标准。 综合以上内容,我们可以看到...

    Java高级面试题附答案汇总(2021年Java面试题及答案大全)

    本资源摘要信息涵盖了Java高级面试题附答案汇总(2021年Java面试题及答案大全),涵盖了多个知识点,包括Java高级面试题、序列化、多线程同步、GC算法、集合类型、JDK自带的监控和性能分析工具等。 1. ...

    Java期末考试题及答案.pdf

    JVM对下列各项做出了定义:指令集、寄存器、类文件格式、栈、垃圾收集堆、存储区。 Java虚拟机的功能包括: * 通过ClassLoader寻找和装载Class文件 * 解释字节码成为指令并执行,提供Class文件的运行环境 * 进行...

    JavaSE知识点总结.doc

    CPU执行指令,内存用于存储程序运行时的数据,硬盘则用于长期存储数据。程序的运行基于冯·诺依曼体系结构,即计算机通过输入、处理、输出和存储四个步骤执行任务。 #### 2. 不同类型语言的编译与运行 编程语言大致...

    Java Web之高级应用

    类装载器是Java应用程序运行的核心组成部分,它负责加载类到JVM中。在Tomcat中,类装载器有明确的层次结构,每个Web应用程序都有自己的类装载器,以确保类的隔离。在示例中,通过context.xml配置资源,如邮件服务,...

    很强的Java加密解密算法

    算法是解决特定问题的步骤或指令集。在加密和解密领域,常见的算法包括对称加密(如DES、3DES、AES)、非对称加密(如RSA、ECC)、哈希函数(如MD5、SHA-1、SHA-256)以及消息认证码(MAC)等。这些算法都有其独特...

Global site tag (gtag.js) - Google Analytics