java内存区域和对象创建过程(初学者理解)

java内存区域

运行时数据区域

线程私有:程序计数器、本地方法栈、java虚拟机栈

线程共享:堆内存、方法区、直接内存(非运行时数据区的一部分)

1、程序计数器:

​ 当前线程所执行的字节码的行号指示器。作用一:选取下一个需要执行的字节码指令,完成分支、循环、跳转、异常处理等功能。作用二:多线程情况下记录当前线程的执行位置,从而当线程切回时,知道这个线程运行到哪里。

2、java虚拟机栈:

​ 每个栈帧存有:局部变量表部分(基本数据类型+refrence引用地址)、方法出口信息、操作数栈、动态链接。补充:调用一个方法时:会经历压栈和弹栈过程。

3、本地方法栈:

​ 虚拟机栈为执行java方法(也就是字节码)服务,本地方法栈为虚拟机使用到的native方法服务。

4、堆:

​ 唯一目的就是存放对象实例。几乎所有对象实例及数组都在这里分配内存。内存又分为:新生代内存、老生代内存、元空间(直接内存)。且运行时的常量池在堆区。

5、方法区:

​ 存储已经被虚拟机加载的类信息、常量、静态变量、编译后的代码等数据。

6、直接内存:

​ 避免在java堆和native堆之间来回复制数据。

对象的创建过程

类加载检查==> 分配内存 ==>初始化零值 ==> 设置对象头 ==> 执行init方法

Step1:类加载检查

​ 虚拟机收到new指令,在常量池中定位这个类的符号引用,判断这个类是否加载过、解析和初始化过,没有就先执行。

Step2:分配内存

​ 在堆中分配内存。

​ 分配方式:指针碰撞、空闲列表。取决于java堆是否规整(有没有内存碎片),是否规整又取决于垃圾收集器是否有压缩整理功能。

Step3:初始化零值

​ 将分配到的内存空间都初始化为零值,保证对象的实例字段在java代码中不赋予初始值就可以直接使用,程序能访问到这些字段的数据类型所对应的零值。

Step4:设置对象头

​ 存储类的元数据(指向类)、对象的哈希码、对象的GC分代等。

Step5:执行init方法

​ 没有执行init方法,所有字段都是零值,执行后才是按照程序员设置的初始值,对象才真正创建出来。

对象的访问定位

使用句柄方式:

​ 堆中划分一块内存作为句柄池,在栈里存储的就是对象的句柄地址,每个对象的句柄地址包括:对象实例数据的指针、对象类型数据的指针。

​ 好处:对象移动时,只需要改变句柄中的指针,而不需要改变栈里的句柄地址

直接指针方式:

​ 栈里存储的就是对象的引用地址,对了实例数据里存储了对象类型数据的指针,指向对象类型。

​ 好处:速度快,直接。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值