您的位置:首页 > 其它

JVM内存模型

2016-05-04 21:13 253 查看
一、程序计数器S(Program Counter Register):

类似于PC寄存器,记录线程的执行位置,线程私有,执行JAVA方法时存储执行指令的地址。

唯一一个在JAVA虚拟机规范中没有规定任何OutOfMemoryError情况的区域。

二、虚拟机栈(VM Stack)

线程私有,每次调用一个方法就开辟一个栈帧,执行结束后弹出。

栈的默认大小是1M。

栈帧(Stack Frame):

{

局部变量表:存放编译期克制的各种基本数据类型、对象引用(reference)和returnAddress类型。其中long 和double类型的数据会占用两个局部变量空间(Slot),其余只占用一个。Slot是可以重用的,但Slot中的变量超出了作用域,那么下一次分配Slot的时候会覆盖原来的数据。Slot对对象的引用会影响GC。

操作数栈:和局部变量区一样,操作数栈也是被组织陈艺戈以字长尾单位的数组。但是操作数栈不是通过索引来访问,而是通过标准的栈操作(压栈和出栈)来访问。

}

三、本地方法栈(Native Stack):

和虚拟机栈相似,但执行Native方法时使用,虚拟机规范对于本地方法帐中方法使用的语言,使用方式和数据结构没有强制规定,最常用的HotSpot虚拟机直接将本地方法栈和虚拟机栈合二为一。

四、JAVA堆(JAVA Heap)

对于大多数应用来说JAVA Heap是JVM说管理的内存中最大的一块。JAVA堆死背所有线程共享的一块内存区域,在虚拟机启动时创建。

JAVA Heap主要用于存放对象实例,几乎所有的对象实例都在这里分配内存。

JAVA Heap是GC的主要区域,分为

{

新生代(The NewGenerational Heap)默认4M,此区域一般为JVM内存的1/15大小

{

Eden区:绝大多数刚创建的对象会分配在Eden区,其中的大多数对象很快就会消亡,Eden区是连续的内存空间,因此在其上分配内存极快。

Survivor区:

{

Survivor区:

当Eden区忙的时候执行Minor GC,并将剩余的对象添加到Survivor区。

Empty Survivor区:

当Survivor区满的时候将其中活着的对象复制到Empty Survivor区,然后清空Survivor区,紧接着现在Empty Survivor区成为Survivor区,

之前的Survivor成为Empty Survivor区,以后Eden区满了活着的对象就会放在当前Survivor区

}

}

老年代(Tenured Genaration)

{

Tenured区:

当一个对象在Survivor两个区游荡了n(可设置)个来回之后,对象进入Tenured区。除此之外,如果对象较大,年轻代空间不足,则大对象会直接分
配到老年代上

}

}

五、方法区(Method Area)

跟堆一样是被各个线程共享的内存区域,用于存储被虚拟机加载的类信息、产量、静态变量。

在JVM启动时创建。

方法区的容量是可以固定大小的,也可以随着程序执行的需求动态扩展,方法区在实际内存空间中可以是不连续的。

/*****************************

//

public class Test {

public static void main(String[] args) {

Test t = new Test();

//JVM将Test类信息加载到方法区, new Test()产生的实例存在堆区,Test引用保存在栈区

}

}

******************************/

六、运行时常量池(Runtime Constant Pool)

运行时常量池实际上是方法区的一部分。在Class文件中,除了有类的版本、极端、方法、接口等描述信息之外,还有一项信息是常量池,用于存放编译期生成的各种字面量和符号引用,这部分内容将在类加载后存放到方法区的运行产量池中。

七、直接内存(Direct Memory)

直接内存比不是虚拟机运行时数据区的一部分,也不是JAVA虚拟机规范中定义的内存区域,但是这部分内存也被频繁的使用,而且有可能导致内存溢出
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: