java内存区域

本文详细介绍了Java虚拟机(JVM)的内存管理机制,包括程序计数器、Java虚拟机栈、栈帧、本地方法栈、Java堆、方法区及常量池的功能与作用。探讨了对象创建过程、内存分配策略及线程安全性,以及HotSpot虚拟机的对象布局和访问方式。
摘要由CSDN通过智能技术生成

内存局域

Java虚拟机所管理的内存包括以下几个运行时内存区域。

程序计数器

线程私有。记录线程正在执行的字节码指令的地址,用于虚拟机在各个线程之间切换时快速恢复到执行位置,在分支,循环,跳转,异常处理线程恢复等基础功能都需要依赖这个计数器来完成。但如果执行的是Native方法,这个计数器的值为undefined,他是唯一没有OutOfMemoryError的区域。

Java虚拟机栈

线程私有。也是我们平时所说的“堆内存”与“栈内存”中的“栈内存”,生命周期与所属线程同生共死, 用于存放栈帧。两种异常:如果线程请求的栈内存大于虚拟机规定的,将抛出StackOverflowError。不过虚拟机大都是可以动态扩展的,一直到扩展而再也申请不到足够内存时,则OutOfMemoryError。

  • 栈帧

每个方法在执行的同时都会创建一个栈帧,生命周期:方法从调用到执行完成对应一个栈帧在虚拟机栈中的入栈与出栈。存储局部变量表,操作数栈,动态链接,方法出口等信息。

  • 局部变量表

存放编译期可知的各种基本数据类型(8种,boolean,byte,char,short...),对象引用(reference类型,指向对象的指针,句柄或其他),returnAddress类型(指向一条字节码指令的地址)。

native栈

线程私有。功能与native方法类似,不同点native栈作用于native方法,java虚拟机栈作用于java方法。有些虚拟机上两者合二为一。

java堆

线程共享,虚拟机管理内存中的最大一块。所有对象实例,数组都在堆上分配(非绝对)。垃圾收集器管理的主要区域。异常:OutOfMemoryError

方法区

线程共享,存储虚拟机加载的类信息,常量池,静态变量,即时编译器后的代码等数据。

  • 常量池

属于方法区,存储编译期生成的各种字面量和符号引用。

       

HotSpot虚拟机在java堆上的分配,布局和访问过程

 

普通对象创建

虚拟机遇到一条new指令时

1.检查常量池中是否有对应类的引用,并检查是否被加载,解析和初始化过,如果没有先进行相应类的加载过程。

2.分配内存。

       “指针碰撞”:假设java堆内存时绝对工整的,已用内存在一边,未用内存在另一边,指针中间标识,分配内存只需移动指针。

        “空闲列表”:java堆内存分配不规整,由一个表来记录已用未用,分配内存时找一块足够大小的内存。

(两种由所采用的垃圾收集器是否带有压缩整理功能决定)

        线程安全:(1):同步锁,(2):在对上预先给每个线程留下空间,平时在这个空间上分配,空间不够了再同步。

3.虚拟机设置对象的基本信息。对象头,实例数据,对其填充。

4.<init>构造函数

 

内存布局

  • 对象头

存储自身运行时数据:hashCode, GC分代年龄,锁状态等等;

类型指针:指向它的类元数据的指针

图片引用地址:https://blog.csdn.net/zhoufanyang_china/article/details/54601311

  • 实例数据

对象真正存储的有效信息,各种字段的值。HotSpot默认顺序 longs/doubles,ints , shorts/chars , bytes , booleans ,oops .

  • 对其填充

占位符的作用。对象的大小必须是8字节的整数倍,没对齐的补齐。

 

对象的方位定位

java程序通过栈上reference数据使用堆上的对象。访问对象方式取决于虚拟机的实现,目前主流句柄和直接指针两种。

  • 句柄

  • 直接指针

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值