java 虚拟机(JVM) 内存模型

1 虚拟机内存分区

线程私有的

  • 程序计数器
    每一个线程都会维护一个程序计数器,内存空间较小,JVM工作的原理就是通过改变程序计算器内的值然后去找到下一条需要执行的字节码指令的地址,分支循环异常等功能都是依赖于它实现的。如果是Native方法则值是underfine。虚拟机规范中唯一一个没有OutOfMemoryError的地方。

  • 虚拟机栈
    线程私有的,生命周期与线程相同,用来描述一个线程方法执行的内存模型,一个java方法的调用会创建一个栈帧用来存储方法的局部变量表,动态链接,方法出口等信息,方法的执行到结束对应一个栈帧的入栈和出栈的过程。
    局部变量表:存放了编译时期可知的各种基本类型数据(int,long,String等)和引用对象(reference类型),returnAdress类型(下一条字节码指令的地址)
    StackOverflowError:线程需要的栈深度超过了虚拟机允许的栈深度。
    OutOfMemoryError:如果虚拟机可以动态扩展,但是内存不足无法申请时。

  • 本地方法栈
    线程私有的,区别于虚拟机栈的是本地方法栈是为Native方法服务的。也有StackOverflowError和OutOfMemoryError错误。

以上三个区域是线程私有的区域,JVM会为每个线程都进行分配。

线程共享的


  • 堆是JVM所管理的内存区域内最大的一块内存。用来存放对象实例和数组。内部会划分出多个线程私有的缓冲区(Thread Local Allocation Buffer),可以位于物理上不连续的区间,但逻辑上连续。
    OutOfMemoryError:没有足够的内存分配给实例并且堆也无法扩展时会报的错误。

  • 方法区:线程共享的,存放已经被类加载的类信息以及静态方法静态变量,常量等,即时编译器编译后的代码数据等。

如图(图是盗的,侵权联系必删)
在这里插入图片描述

运行时常量池:存放运行时产生的产量(例如Sting类的字符串常量池),也称为永久代,jdk1.7之前在方法区内,1.7在堆内,1.7之后永久代变成了元空间。

直接内存:非虚拟机运行时数据区的内存。

2.对象的产生以及内存模型

对象的产生过程比较复杂,有空我再深究。

对象的内存模型
在HotSpots虚拟机中,对象分为三部分。
对象头:分为两部分,一部分是对象的标记字段,例如哈希码,锁状态标志,GC分代年龄,线程持有的锁,偏向线程Id,偏向时间戳等,另一部分是类型指针,指向对象所属类的元数据。
实例数据:对象所定义的各种类型的字段内容。(包含父类继承下来的)
对齐填充:对象的启始位置在内存中是8的倍数,所以不够8N字节的部分会进行填充。还有字段间的填充,保证每个字段都能一次性读入CPU缓存(8字节)。

tips:欢迎来我的个人网站溜达溜达http://www.wsjiu.com/

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值