JVM中的堆和栈

来源:互联网 发布:网络加油站网站 编辑:程序博客网 时间:2024/05/02 04:56

JVM 全名是Java Virtual Machine

它是负责跨平台的已编译的一小段代码,这里的平台包括硬件和操作系统。

JAVA对JVM,它只解析特定格式的文件class,你可以用任何语言去写代码,只要按照class的语法生成文件,JVM都可以解析。

JVM和java一样有两种类型变量

原始类型

引用类型

运行时数据:

堆-JVM启动的时候,就已经分配出一块内存给堆了。堆里面的信息可以在线程之间共享

栈-JVM的每创建一个进程,就会创建一个私有的栈给这个进程。当线程的生命周周期结束了,这个栈也释放了。如果用到native的方法,那么JVM还有创建一个native stack

每个非native线程都有一个PC(process count)

PC会注册当前运行的方法地址,用来定位每个方法的位置,可以记录线程的执行轨迹。比如多个线程抢占CPU,当一个线程失去CPU的使用权,当它获得资源的,就是用PC回到上次执行的。

JVM stack的分配

用户可以自己配置,可以是固定的,也可是的动态分配的。Stack不需要连续的内存。Stack是每个线程私有的,它存储局部变量和结果。每个线程都有一个stack。stack里面包含的信息叫做frame。帧里面包含了一个本地变量数组,操作数stack,symbolic linking。

如果超过stack准许的最大值,Java会抛出StackOverflowError

如果stack是动态分配的,但是物理机器没有足够的内存可用,则抛OutOfMemoryError

堆和non-heap:

堆是JVM启动时候就已经分配,每个线程可以共享的内存,它也不需要连续的存储块。它包含了一些class的信息,构造,方法,字段等。它包含了下面信

---方法区

           它也是属于non-head(非堆)里面的内容,它包含了class的结构,运行时的常量池,字段,方法数据,还包括了具体的代码。这个内存里面的数据可以不用GC。class的实例分配在真正的堆里面。

--- 常量池

           它属于方法区里面的信息。包含了原始常量和引用常量。     

Frames

farme被push到stack里面。每一个执行一个方法都会创建一个frame,它包含局部变量数组,操作数栈,指向当前class的常量池的引用和方法的返回值。

Frames里面有一个当前frame。Frame是和方法生命周期共存的。

 

Local variable array每个位置只能存储一个32位的变量,如果是long或者double,就必须占用2个位置

Local variable array如果是从class里面调用方法,方法参数从0位开始

如果是instance方法,则从1 index开始,0留给this引用

例如JVM 用istore_1把操作栈顶部的一个int值存入到local variable arry里面,index是1.

Operand Stacks

操作数栈

Jvm指令用operand stacks里面的数值做运算,然后将结果再push到stack里面。比如用aload_0,把local variable arry的index为0存储的值,push到stack里面。为下面的其他操作指令做好准备。

Long和double占stack 2个depth位。

Dynamic linking

链接到class的常量池

这张图可以体现上面的JVM architecture:

 

0 0
原创粉丝点击