JVM学习之:浅谈方法调用

标签: jvm 学习 方法 | 发表时间:2012-09-25 22:22 | 作者:sun7545526
出处:http://blog.csdn.net

提到方法调用,我想大多数人的第一反应就是执行一个方法呗,其实在虚拟机的眼里方法调用只是确定他要调用哪个方法而已,和方法的执行还是有比较大的区别的.任何一个层序的运行都离不开方法的调用以及方法的执行,但是在 JVM学习之:虚拟机中的运行时栈帧总结(二)提到过,在Class文件的编译过程中不包括传统的连接步骤(连接:把符号引用转化为可以直接找到方法体的直接引用),但是正是因为这点也给java带来了更大的灵活性,因为不同的实现可能会在不同的阶段对符号引用进行转化,下面是对几种常见的方法调用类型进行描述


解析:

JVM学习之:虚拟机中的运行时栈帧总结中提到了,如果符号引用是在类加载阶段或者第一次使用的时候转化为直接应用,那么这种转换成为 静态解析,那么什么样的方法会在这个阶段进行转换了?虚拟机规范提到,只有在真正运行之前就可以确定调用版本的,并且在运行时是不可变的方法,简单的讲,也就是不能被覆盖.不能被改变,不能被重载的方法,其实也就是static方法,private方法,final方法,<init>构造器,父类方法,这几种方法都是适合在类加载解析阶段讲符号引用转换为直接引用的,对这写种类方法的调用也被称为 解析.除了这些方法的其他方法也被称作为 虚方法()

前面提到了几种方法的调用,虚拟机也提供了对应的字节码指令,分别是:

invokestatic:调用静态方法

invokespecial:调用构造器方法,私有方法以及父类方法

invokevirtual:调用虚方法以及final方法(虽然用invokevirtual调用,可是因为final方法的不可覆盖性,因此也是非虚方法)

invokeinterface:调用接口方法,会在运行时再确定一个具体的实现方法


下面通过一个演示类的反编译结果来对上面的字节码指令进行验证:

package com.eric.jvm.executor;

/**
 * 通过反编译字节码来验证 
 * invokestatic:调用静态方法 
 * invokespecial:调用构造器方法,私有方法以及父类方法
 * invokevirtual:调用虚方法以及final方法(虽然用invokevirtual调用,可是因为final方法的不可覆盖性,因此也是非虚方法)
 * invokeinterface:调用接口方法,会在运行时再确定一个具体的实现方法
 * 
 * 
 * javap -verbose com.eric.jvm.executor.InvokeCommandExecutor
 * 
 * @author Eric
 * 
 */
public class InvokeCommandExecutor {
	
	
	public static void main(String[] args) {
		//invokestatic
		SubInvoker.invokeStatic();
		//invokespecial,
		SubInvoker si=new SubInvoker();
		//invokevirtual
		si.invokeVirtual();
		//invokeinterface
		si.invokeInterface();
	}
	
}

class SubInvoker implements IExecutor{
	public static void invokeStatic(){
		System.out.println("invokestatic was execute");
	}
	public SubInvoker(){
		System.out.println("invokespecial was execute in construct");
	};
	public void invokeVirtual(){
		System.out.println("invokevirtual was execute");
	}
	@Override
    public void invokeInterface() {
		System.out.println("invokeinterface was execute");
    }
}

interface IExecutor{
	public void invokeInterface();
}

反编译后的相关的指令片段:对应main中的方法调用顺序





分派:

众所周知,面向对象的三个特点是:"继承,封装,多态",其中多态又包括覆盖和重载,本节提到的分派就是覆盖和重载的底层实现基础.那么让我们来看看什么是分派?分派和解析属于同一个范畴的概念,都是方法调用的类型而已,只是分派比解析要稍微的复杂一点,分派的符号应用可以再类加载阶段进行转换,也可以再运行时进行转换,而且根据宗量也可能存在单个宗量以及多个宗量,下面将分别对其种类进行说明:


静态分派:


动态分派:




作者:sun7545526 发表于2012-9-25 22:22:52 原文链接
阅读:0 评论:0 查看评论

相关 [jvm 学习 方法] 推荐:

JVM学习之:浅谈方法调用

- - CSDN博客推荐文章
前面提到了几种方法的调用,虚拟机也提供了对应的字节码指令,分别是:. invokestatic:调用静态方法. invokespecial:调用构造器方法,私有方法以及父类方法. invokevirtual:调用虚方法以及final方法(虽然用invokevirtual调用,可是因为final方法的不可覆盖性,因此也是非虚方法).

学习JVM的References

- LightingMan - 淘宝JAVA中间件团队博客
本blog中列举了我学习JVM的references,会不断的更新,为了避免版权问题,就不在blog上提供references的下载了,感兴趣的同学可自行下载或购买,:). |— [ Hotspot GC论文 ]. |— [ 其他JVM GC ]. |— Linux内核源代码情景分析. |— Linux 内核中断内幕.

JVM学习 - 体系结构

- - CSDN博客推荐文章
一:Java技术体系模块图. 二:JVM运行时内存区域模型. 也称"永久代” 、“非堆”,  它用于存储虚拟机加载的类信息、常量、静态变量、是各个线程共享的内存区域. 可以通过-XX:PermSize 和 -XX:MaxPermSize 参数限制方法区的大小. 运行时常量池:是方法区的一部分,Class文件中除了有类的版本、字段、方法、接口等描述信息外,还有一项信息是常量池,用于存放编译器生成的各种符号引用,这部分内容将在类加载后放到方法区的运行时常量池中.

JVM监控方法 - JvmMonitor

- - 编程语言 - ITeye博客
        在日常项目运作中,有时我们需要将JVM的信息以我们期望的方式输出到日志中,然后对日志对日志进行实时监控. 说明:记录了jvm中的一些堆内存和线程信息以及堆外内存,例. 格式:(used_heap,max_heap)(current_thread_cpu_time,daemon_thread_count,total_thread_count,total_started_thread_count)(non_heap_reserved_memory,non_heap_max_memory).

JVM内存管理学习总结(一)

- - CSDN博客互联网推荐文章
I.JVM进程的生命周期. JVM实例的生命周期和java程序的生命周期保持一致,即一个新的程序启动则产生一个新的JVM进程实例,程序结束则JVM进程实例伴随着消失. 那么程序启动和程序终止就是JVM实例生命周期的两个边界,两个边界点可以这么理解:一个拥有程序入口(main函数)的class在执行main方法时,相应的JVM就被创建了(即JVM生命周期的起点),当由此main函数启动的所有非守护线程都终止时,JVM即退出(JVM实例生命周期的终点).

JVM学习笔记(六):类加载的时机

- - ITeye博客
本文根据《深入理解java虚拟机》第7章部分内容整理.     Java虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的加载机制.    类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括了:加载(Loading)、验证(Verification)、准备(Preparation)、解析(Resolution)、初始化(Initialization)、使用(using)、和卸载(Unloading)七个阶段.

JVM 调优 —— GC 长时间停顿问题及解决方法

- - ImportNew
垃圾收集器长时间停顿,表现在 Web 页面上可能是页面响应码 500 之类的服务器错误问题,如果是个支付过程可能会导致支付失败,将造成公司的直接经济损失,程序员要尽量避免或者说减少此类情况发生. 并发模式失败(concurrent mode failure). 在 CMS 启动过程中,新生代提升速度过快,老年代收集速度赶不上新生代提升速度.

JVM研究

- - 开源软件 - ITeye博客
每天接客户的电话都是战战兢兢的,生怕再出什么幺蛾子了. 我想Java做的久一点的都有这样的经历,那这些问题的最终根结是在哪呢. JVM全称是Java Virtual Machine,Java虚拟机,也就是在计算机上再虚拟一个计算机,这和我们使用 VMWare不一样,那个虚拟的东西你是可以看到的,这个JVM你是看不到的,它存在内存中.

jvm调优

- - 互联网 - ITeye博客
printf "%x\n" 21742  找到耗时最长的进程. jstack pid | grep 54ee  定位某个类的方法. jstack 10535|grep -A 10 2a1d (最后十行). jmap 查询pid 内存线程. 附:TOP命令中需要关注的值:. (1)load average:此值反映了任务队列的平均长度;如果此值超过了CPU数量,则表示当前CPU数量不足以处理任务,负载过高.

深入理解JVM

- 小伟 - ITeye论坛最新讨论
1   Java技术与Java虚拟机. 说起Java,人们首先想到的是Java编程语言,然而事实上,Java是一种技术,它由四方面组成: Java编程语言、Java类文件格式、Java虚拟机和Java应用程序接口(Java API). 图1   Java四个方面的关系. 运行期环境代表着Java平台,开发人员编写Java代码(.java文件),然后将之编译成字节码(.class文件).