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虚拟机规范中定义的内存区域,但是这部分内存也被频繁的使用,而且有可能导致内存溢出
类似于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虚拟机规范中定义的内存区域,但是这部分内存也被频繁的使用,而且有可能导致内存溢出
相关文章推荐
- Android Handler详细使用方法实例
- view阴影
- HDU 1397 Goldbach's Conjecture(素数判断)
- 数据结构_线性表_顺序表 的创建,插入,删除,查找
- Android 触摸事件机制(三) View中触摸事件详解
- win8/Metro开发系列一 Xaml布局
- python---基础知识
- scikit-learn学习之SVM算法
- Java 泛型(二) 泛型之中的通配符(Wildcards)使用
- ReactNative真机调试
- Linux内核 定时器 用法
- Java之DriverManager简单介绍
- Add Two Numbers
- check the manual that corresponds to your MySQL server version for the right syntax to use near 'USI
- Android中ListView内容超过一屏,上下滑动后数据紊乱的问题
- Java 泛型(一) 泛型使用基础
- 冒泡排序
- Android基础 | 控件基础 | RadioGroup用法
- NIO边看边记 之 通道之间的数据传输(五)
- XMG 触摸事件的处理过程