JVM规格书中没有规定对象和数组在JVM的内存内是如何呈现的,只提到所有的对象都要通过reference来寻址.具体可以看看. 另外可以看看这个 : Each Java virtual machine thread has a private Java virtual machine stack, created at the same time as the thread. A Java virtual machine stack stores frames . A Java virtual machine stack is analogous to the stack of a conventional language such as C it holds local variables and partial results, and plays a part in method invocation and return. Because the Java virtual machine stack is never manipulated directly except to push and pop frames, frames may be heap allocated. The memory for a Java virtual machine stack does not need to be contiguous. frame的定义: A frame is used to store data and partial results, as well as to perform dynamic linking , return values for methods, and dispatch exceptions. A new frame is created each time a method is invoked. A frame is destroyed when its method invocation completes, whether that completion is normal or abrupt (it throws an uncaught exception). Frames are allocated from the Java virtual machine stack of the thread creating the frame. Each frame has its own array of local variables , its own operand stack , and a reference to the runtime constant pool of the class of the current method. 至于 "静态属性保存在stack指令内存区,动态属性保存在heap数据内存区" 的问题,建议尽量使用 公认的名词来交流.不知道看到这里楼主明白了没有.
为了避免误导,还是由我来总结一下: 1.非静态方法和静态方法的不同:非静态方法有一个隐含的传入参数,该参数是JVM给它的类实例, 静态方法也有一个隐含的传入参数,该参数是该类的Class对象的引用,这里有点难理解,需要弄明白Class A 和 A.class这两个概念的不一样. 2.静态属性和动态属性: 正式的说法是静态成员变量和动态成员变量,从以下可以看出静态成员变量和动态成员变量都是存放在堆中的. The Java virtual machine has a heap that is shared among all Java virtual machine threads. The heap is the runtime data area from which memory for all class instances and arrays is allocated.
sorry 打错了
不过我有个问题想问问,stack 定长,并且顺序分配!
现在我的问题就是,
类的静态方法在 classLoader是 push stack,那么在什么时候弹出 stack??
学汇编的时候,有寄存器是cs和ss吧
cs:ip就构成了你现在要执行的指令地址,而当你调用函数的时候,会将当前的cs:ip值压入堆栈
然后cs:ip就指向了你调用的函数的地址,等调用完了,在将原来的cs:ip弹出回来jvm我还真不懂
没时间考虑呀,头痛中!
疑点:为什么实例属性保存在heap中就可以推出类属性是保存在stack中的?姑且不讨论文中的用语和结论,先接分,有空再仔细研究研究。
谢谢!!
UP UP UP11
栈是用来存放调用method时保护现场的数据的地方!
在方法里的 new 出来的refrence 和 int xxx = xxxx 的xxx所在空间也是放在那里的.
你需要的是保证你的代码没有作无用的浪费,再就是选择一个
合适的JVM或者调整JVM的参数。
invokestatic,将静态方法的参数压栈,然后调用执行该指令就可以了,返回值放到栈顶。
其实实际要远比我说的复杂,至少我知道堆是很复杂的,有什么全局堆等等JVM 的实现 我没有研究过,也没有看过具体不知道他是怎么实现的你的栈的意思也是从 微机原理 得来的吧那按照你的意思,因该说 这个名称可能不太对
是说栈指令区,而不是单说栈,你明白我的意思吗?不过这是我的理解,也许不一定正确
obj1和obj2是同一个类的对象,则obj1.getClass()==obj2.getClass()
另外在对synchronized对静态方法同步的时候,其实其对象锁就应该是Class对象,而不是Object。
另外可以看看这个 :
Each Java virtual machine thread has a private Java virtual machine stack, created at the same time as the thread. A Java virtual machine stack stores frames . A Java virtual machine stack is analogous to the stack of a conventional language such as C it holds local variables and partial results, and plays a part in method invocation and return. Because the Java virtual machine stack is never manipulated directly except to push and pop frames, frames may be heap allocated. The memory for a Java virtual machine stack does not need to be contiguous.
frame的定义:
A frame is used to store data and partial results, as well as to perform dynamic linking , return values for methods, and dispatch exceptions.
A new frame is created each time a method is invoked. A frame is destroyed when its method invocation completes, whether that completion is normal or abrupt (it throws an uncaught exception). Frames are allocated from the Java virtual machine stack of the thread creating the frame. Each frame has its own array of local variables , its own operand stack , and a reference to the runtime constant pool of the class of the current method. 至于 "静态属性保存在stack指令内存区,动态属性保存在heap数据内存区" 的问题,建议尽量使用
公认的名词来交流.不知道看到这里楼主明白了没有.
http://java.sun.com/docs/books/vmspec/2nd-edition/html/VMSpecTOC.doc.html
1.非静态方法和静态方法的不同:非静态方法有一个隐含的传入参数,该参数是JVM给它的类实例,
静态方法也有一个隐含的传入参数,该参数是该类的Class对象的引用,这里有点难理解,需要弄明白Class A 和 A.class这两个概念的不一样.
2.静态属性和动态属性:
正式的说法是静态成员变量和动态成员变量,从以下可以看出静态成员变量和动态成员变量都是存放在堆中的.
The Java virtual machine has a heap that is shared among all Java virtual machine threads. The heap is the runtime data area from which memory for all class instances and arrays is allocated.
JVM定义了控制Java代码解释执行和具体实现的五种规格,它们是:
JVM指令系统
JVM寄存器
JVM栈结构
JVM碎片回收堆
JVM存储区
2.1JVM指令系统 JVM指令系统同其他计算机的指令系统极其相似。Java指令也是由 操作码和操作数两部分组成。操作码为8位二进制数,操作数进紧随在操作码的后面,其长度根据需要而不同。操作码用于指定一条指令操作的性质(在这里我们采用汇编符号的形式进行说明),如iload表示从存储器中装入一个整数,anewarray表示为一个新数组分配空间,iand表示两个整数的"与",ret用于流程控制,表示从对某一方法的调用中返回。当长度大于8位时,操作数被分为两个以上字节存放。JVM采用了"big endian"的编码方式来处理这种情况,即高位bits存放在低字节中。这同 Motorola及其他的RISC CPU采用的编码方式是一致的,而与Intel采用的"little endian "的编码方式即低位bits存放在低位字节的方法不同。
Java指令系统是以Java语言的实现为目的设计的,其中包含了用于调用方法和监视多先程系统的指令。Java的8位操作码的长度使得JVM最多有256种指令,目前已使用了160多种操作码。
2.2JVM指令系统
所有的CPU均包含用于保存系统状态和处理器所需信息的寄存器组。如果虚拟机定义较多的寄存器,便可以从中得到更多的信息而不必对栈或内存进行访问,这有利于提高运行速度。然而,如果虚拟机中的寄存器比实际CPU的寄存器多,在实现虚拟机时就会占用处理器大量的时间来用常规存储器模拟寄存器,这反而会降低虚拟机的效率。针对这种情况,JVM只设置了4个最为常用的寄存器。它们是:
pc程序计数器
optop操作数栈顶指针
frame当前执行环境指针
vars指向当前执行环境中第一个局部变量的指针
所有寄存器均为32位。pc用于记录程序的执行。optop,frame和vars用于记录指向Java栈区的指针。
2.3JVM栈结构
作为基于栈结构的计算机,Java栈是JVM存储信息的主要方法。当JVM得到一个Java字节码应用程序后,便为该代码中一个类的每一个方法创建一个栈框架,以保存该方法的状态信息。每个栈框架包括以下三类信息:
局部变量
执行环境
操作数栈
局部变量用于存储一个类的方法中所用到的局部变量。vars寄存器指向该变量表中的第一个局部变量。
执行环境用于保存解释器对Java字节码进行解释过程中所需的信息。它们是:上次调用的方法、局部变量指针和操作数栈的栈顶和栈底指针。执行环境是一个执行一个方法的控制中心。例如:如果解释器要执行iadd(整数加法),首先要从frame寄存器中找到当前执行环境,而后便从执行环境中找到操作数栈,从栈顶弹出两个整数进行加法运算,最后将结果压入栈顶。
操作数栈用于存储运算所需操作数及运算的结果。
2.4JVM碎片回收堆
Java类的实例所需的存储空间是在堆上分配的。解释器具体承担为类实例分配空间的工作。解释器在为一个实例分配完存储空间后,便开始记录对该实例所占用的内存区域的使用。一旦对象使用完毕,便将其回收到堆中。
在Java语言中,除了new语句外没有其他方法为一对象申请和释放内存。对内存进行释放和回收的工作是由Java运行系统承担的。这允许Java运行系统的设计者自己决定碎片回收的方法。在SUN公司开发的Java解释器和Hot Java环境中,碎片回收用后台线程的方式来执行。这不但为运行系统提供了良好的性能,而且使程序设计人员摆脱了自己控制内存使用的风险。
2.5JVM存储区
JVM有两类存储区:常量缓冲池和方法区。常量缓冲池用于存储类名称、方法和字段名称以及串常量。方法区则用于存储Java方法的字节码。对于这两种存储区域具体实现方式在JVM规格中没有明确规定。这使得Java应用程序的存储布局必须在运行过程中确定,依赖于具体平台的实现方式。
大家可以看一下这些资料
http://www.artima.com/java/index.html
http://joeq.sourceforge.net/纯java写的一虚拟机,可以参考一下它的实现。
基本思想应该是一样的