欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java Stack, Frame, Operand Stack JavaJVMthread浏览器Security

程序员文章站 2022-03-14 18:39:51
...
我浏览JavaEye时间挺久,不过很长时间只潜水,连个账户都是2006年春天才申请。2006年八月初发表了第一个帖子,是回答一个网友关于JVM的问题。JavaEye升级到2.0之后,别的帖子都转过来了,唯独这一篇除外。幸好当初留了个草稿。

原来的问题,是问Inside The Java Virtual Machine一书中一段话是什么意思:

引用
The bytecode streams that represent Java methods are a series of one-byte instructions, called opcodes, each of which may be followed by one or more operands. The operands supply extra data needed by the Java Virtual Machine to execute the opcode instruction. The activity of executing bytecodes, one opcode after another, constitutes a thread of execution inside the Java Virtual Machine. Each thread is awarded its own Java Stack, which is made up of discrete frames. Each method invocation gets its own frame, a section of memory where it stores, among other things, local variables and intermediate results of computation. The part of the frame in which a method stores intermediate results is called the methodís operand stack. An opcode and its (optional) operands may refer to the data stored on the operand stack or in the local variables of the methodís frame. Thus, the virtual machine may use data on the operand stack, in the local variables, or both, in addition to any data stored as operands following an opcode when it executes the opcode.



(这一段我是从第一版的第三章Security,章节Phase One: Internal Checks里摘下来的,在第二版里估计没有什么变动,但章节可能不一样)

这里面有三个关键词:
  • Java Stack
  • Frame
  • Operand stack (注意,这个stack和第一个不是一回事,下面会提到。)


线程是执行一条条机器指令的,文章中The activity of executing bytecodes, one opcode after another, constitutes a thread of execution inside the Java virtual machine 是指这个意思。原网友误解成一个又一个的opcode组成了thread,这不对。一个又一个的opcode不组成thread,而是对一个又一个opcode的执行,组成了thread,(activity of executing bytecodes)

Java程序由调用main方法开始,这是第一个方法调用,由main调用另外个方法,这就开始了个新的调用。每一次调用,就生成一个新的frame。

在创建thread的时候,JVM给thread独建一个属于这个thread自己的Java Stack, 然后开始调用main,调用main就建立第一个frame,放在Java Stack里。从main调用另外个方法,生成个新的frame,放在Java Stack最顶上,调用结束,这个最顶上的frame去掉。可以想象java thread在执行时,随着方法调用,Java Stack里面frame增增减减。所以说Java Stack是由一个个frame组成的。

(可以玩玩这个Thread.currentThread().dumpStack(); 就明白了。)

Discrete frames 这里该理解成一个个的frame, 而不是“不连续的frame”。

那么frame里面放的是什么东西呢?翻翻任意一本讲编译器的书,都说里面有这个方法(函数)调用传的参数,返回地址,和局部变量。在jvm里,还有一个叫做operand stack的东东。

我们现在用的计算机,都是寄存器架构的(register machine). JVM 和 .NET Virutal Machine, 都是stack machine. 这两者有什么区别呢?计算一个简单的表达式:1+2,用opcode和operand表达就是add 1, 2   在register machine里面,先把1放在第一个寄存器里面,2放在第二个寄存器里面,运算时从那两个寄存器里取值,结果放在第三个寄存器里面。在jvm里,则是先把1 push到operand stack里,再把2 push 到 operand stack 里,运算时pop 两下把1和2取出来,结果3再push回 operand stack 里面。

运行1+2+3+a, 除了operand stack 之外,还要取局部变量a的值,那段英文的最后一句话指的就是这个。

最后说一句,Java Stack,frame,operand stack,都是内存里面的一块地方。