您的位置:首页 > 编程语言 > Java开发

Java虚拟机内存区域

2016-05-22 23:29 302 查看


Java虚拟机


自动内存管理




运行时数据区域

程序计数器

较小的一块内存空间,可以看做当前线程所执行的字节码的行号指示器,字节码指示器通过改变这个计数器的值类选取下一条需要执行的字节码指令

每个线程都有一个独立的程序计数器,这类内存区域称为“线程私有”的内存(线程私有)

如果线程正在执行一个Java方法,这个计数器记录的是正在执行的虚拟机字节码指令地址,如果正在执行的Native方法,这个计数器值则为空。这个内存区域是唯一一个没有OutOfMemoryError情况的区域

Java虚拟机栈

与程序计数器一样也是线程私有,虚拟机栈描述的是是Java方法执行的内存模型:每个方法都会创建一个栈帧用于存储局部变量表,操作数栈,动态链接,方法出口等信息

局部变量表存放了编译器可知的基本数据类和对象引用类型
如果线程请求的栈深度大于虚拟机所运行的深度,将抛StackOverflowError异常 申请不到足够的内存会抛OutOfMemoryError异常

本地方法栈

本地方法栈与虚拟机所发挥的作用类似,为本地方法Native方法服务,也会抛StackOverflowError和OutOfMemoryError异常,有的虚拟机会将本地方法栈和虚拟机方法栈合二为一

Java堆

内存最大的一块
所以线程共享
唯一目的存放对象实例
Java堆是垃圾收集管理的主要区域(有时被称为GC堆)
可以通过Xmx和Xms控制(xms指你的程序的初始化内存大小,xmx指定你的程序占用的最大内存)

方法区(Java虚拟机规范把方法描述为堆的一个逻辑部分,但它有个别名却叫Non-Headp非堆,应该与Java堆区分开)

方法区也是线程共享的区域,用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码数据

在HotSpot虚拟机上开发的开发者把方法区称为“永久代”,但面临这内存溢出题,用永久代来实现方法区并不好

运行时常量池(方法区的一部分)

直接内存(不是虚拟机运行时数据区的一部分)


HotSpot虚拟对象探秘

对象创建



对象的内存布局

对象头(Header)、实例数据(Instance Data)和对齐填充(Padding)

对象头

第一部分:哈希码,Gc分代年龄,锁状态标志,线程持有的锁,偏向线程ID,偏向时间戳
另一部分:类型指针来确定对象是那个类的实例

实例数据:存储了有效数据

对齐填充:占位符

对象的访问

句柄访问:在堆中划出一片句柄池(具体地址信息),而栈中引用存储的是句柄地址
直接访问
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: