前言
这篇里的东西,其实是我在草稿箱里找到的.因为当时写的比较粗,而且这个题目的内容没有完结..所以一直没有发布.但是后续有篇文章
java中 obj=null对垃圾回收有用吗
要引用里面局部变量表的知识,所以就先把这个半吊子发布出来,后续慢慢补充.
类执行机制
jvm采用中间码来实现执行.其中,方法执行的指令有下面几个
(1)invokestatic 执行static方法
(2)invokevirtual 调用对象实例方法
(3)invokeinterface 调用接口方法
(4)invokespecial 调用private方法和Init方法
上面说的其实有点笼统,invokevirtual和invokespecial的知识可以看一下 Java方法分派 里面说的比较详细.
另外,jdk7以后新增了一条方法执行 invokedynamic 提供了一条对动态语言的支持.可惜在jdk7没有在java语言中支持该指令. 可以看一下 http://rednaxelafx.iteye.com/blog/477934
sun JDK基于栈的体系来执行字节码.线程在创建后,都会产生程序计数器(PC register)和栈(Stack),其中程序计数器存放要执行的指令在方法内的偏移量,栈当中存放栈帧,每个方法每次调用都会产生栈帧.
注:该图来自 毕玄的书 <发布式Java应用基础和实践>
局部变量区用于存放方法中的局部变量和参数,操作数栈用于存放方法执行过程中的中间结果.
可以这么理解,任何在方法体中特意定义过的局部变量,那么都会放到局部变量表(方法参数也会放这里).其他的中间结果.具体看下面的例子
可以这么理解,任何在方法体中特意定义过的局部变量,那么都会放到局部变量表(方法参数也会放这里).其他的中间结果.具体看下面的例子
public class Test { public int add(int a,int b){ int c = a + 1; return c * b; } }看javap输出
首先要说明的是,按照之前的说法,方法参数会放到局部变量表中.所以局部变量表中的第一个值对应add方法的参数a,第二个值对应于参数b.
写道
public int add(int, int);
Code:
Stack=2, Locals=4, Args_size=3
0: iload_1 //将局部变量表中第一个值压入操作数栈(这个值对应add方法中的参数a)
1: iconst_1 //将int 类型的 1 放入操作数栈.
2: iadd //执行add指令. 将操作数栈顶两个元素相加,然后把结果放到栈顶 (a + 1)
3: istore_3 //把栈顶元素放到局部变量表中的第三个位置.也就是c
4: iload_3 //把局部变量表第三个元素压入栈顶,也就是c
5: iload_2 //把局部变量表第二个元素压入栈顶,也就是b
6: imul //执行mul指令,将栈顶两个相乘,然后把结果放入栈顶,也就是 c * b
7: ireturn //把栈顶元素返回.
LineNumberTable:
line 8: 0
line 9: 4
}
Code:
Stack=2, Locals=4, Args_size=3
0: iload_1 //将局部变量表中第一个值压入操作数栈(这个值对应add方法中的参数a)
1: iconst_1 //将int 类型的 1 放入操作数栈.
2: iadd //执行add指令. 将操作数栈顶两个元素相加,然后把结果放到栈顶 (a + 1)
3: istore_3 //把栈顶元素放到局部变量表中的第三个位置.也就是c
4: iload_3 //把局部变量表第三个元素压入栈顶,也就是c
5: iload_2 //把局部变量表第二个元素压入栈顶,也就是b
6: imul //执行mul指令,将栈顶两个相乘,然后把结果放入栈顶,也就是 c * b
7: ireturn //把栈顶元素返回.
LineNumberTable:
line 8: 0
line 9: 4
}
补充说明一下,
写道
其实局部变量表是有第零个元素的.不过一般这个元素都是指向this.如果把方法改成static,就可以看到第一个方法参数(也就是a) 就是以iload_0来压栈了.
栈顶缓存
从上面的例子看到,我们计算 c * b 的时候,需要从存放c的寄存器(也就是第三个局部变量表的元素)先压入操作数栈的栈顶,然后再计算相乘操作.而栈顶缓存的效果就是,取消压栈的这次操作,直接把寄存器的数据拿来做相乘操作,然后把结果压入栈.
-----未完待续
相关推荐
通过此文章,我们可以简单的认识一下java程序的运行机制。
详细的介绍了java运行过程及机制,希望对你学习java开发有帮助。
了解Java的运行机制,能够更好的帮你理解Java语言
Java内存模型.mht.一部很不错的书。可以好好看下,对你有很大的帮助,对理解java的运行机制有更深刻的理解!
Java虚拟机运行机制Java虚拟机运行机制Java虚拟机运行机制Java虚拟机运行机制
Java 反射机制 代码的实例 请认真阅读 运行此代码 只要读懂了 反射机制也就明白了
java程序的运行机制详细分析,很基础的东西,但是很容易被忽略的部分
Java虚拟机解释执行机制研究.pdf
Java 反射机制、Java 的类反射机制、Java 反射机制的学习、Java 反射Reflection--运行时生成实例 java反射机制的手册文档
java运行机制 java核心机制 java虚拟机 jvm java virtual machine 1. jvm是一个虚拟的计算机,具有指令集并使用不同的存储区域。负责执行管理数据、内存、寄存器,包含在JDK中 2. 不同平台,不同虚拟机 3. java...
垃圾收集GC(Garbage Collection)是Java语言的核心技术之一,之前我们曾专门探讨过Java 7新增的垃圾回收器G1的新特性,但在JVM的内部运行机制上看,Java的垃圾回收原理与机制并未改变。垃圾收集的目的在于清除不再...
Java零基础学习资料
在Java运行时环境中,对于任意一个类,能否知道这个类有哪些属性和方法?对于任意 一个对象,能否调用它的任意一个方法?答案是肯定的。这种动态获取类的信息,以及动态 调用对象的方法的功能来自于Java 语言的反射...
3.2.1 Java反射机制的概念 Java反射机制在Java运行状态中,对于任意一个类,我们都能够知道这个类的所有属性和方法;, 对于任意一个对象,我们都能够调用它的任意一个方法;。 这种动态获取的信息以及动态调用对象...
有时候我们说某个语言具有很强的动态性,有时候我们会区分动态和静态的不同技术与作法。我们朗朗上口动态绑定(dynamic binding)、动态链接(dynamic ...是可以通过反射机制来实现“动态”,用一个实例来说明一下:
文档中介绍了: 寄存器 栈 堆 静态域 常量池 帮助java学习者从本质上理解java的运行机制。
Java运行环境(Java Runtime Environment,JRE)是一种用于执行Java程序的软件环境。它包含了Java虚拟机(Java Virtual Machine,JVM),以及Java核心类库和运行时所需的其他组件。 JRE的主要作用是提供Java应用...
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。 Java...
一般而言,开发者社群说到动态语言,大致认同的一个定义是:“程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言”。从这个观点看,Perl,Python,Ruby是动态语言,C++,Java,C#不是动态语言。
Java程序的编译运行有两种方式:在JVM上动态编译执行其class文件,和静态编译成可执行程序。相比于动态编译执行Java程序,在某些情况下,将Java程序静态编译成本地代码的执行模式,可以获得更好的性能.本文提出了一种...