java内存区域
本章是学习java内存区域后的简结
分为:
1.内存区域的介绍(运行时数据区)
2.java创建对象的步骤
3.对象的访问方式
一、内存区域
java虚拟机,在执行java程序时,会把他所管理的内存分为若干个不同的数据区域。
1.程序计数器
程序计数器是一块小的内存空间,可以看做是当前线程所执行的字节码文件的行号指示器。字节码解释器工作时,将高级编程语言直接转译运行,在此过程中,需要程序计数器来指示下一条需要执行的字节码指令。
此外,为了保证线程切换后能恢复到正确位置,每条线程都需要一个程序计数器,彼此互不影响。所以程序计数器是私有的。
2.java虚拟机栈
java虚拟机栈可以粗浅的理解为栈内存空间。主要存储了编译器可知的各种数据类型和对象引用。
数据类型主要包括八大类型(boolean byte char short int float long double )
对象引用(他不是对象本身,可能是一个指向对象起始地址值的引用指针,也可能是一个指向对象的句柄或其他与此对象有关的位置)
java虚拟机栈也是私有的,他的生命周期和线程相同
3.本地方法栈
和虚拟机栈非常相似,区别是:
虚拟机栈为虚拟机执行java方法,也就是字节码文件服务。
本地方法栈为为虚拟机使用到的Native方法服务
Native方法简单的讲就是一个java调用非java代码时所用的接口。
本地方法栈也是私有的。
4.堆
堆是虚拟机管理内存中最大的一块,在虚拟机启动时创建,负责存放实例变量。几乎所有的实例变量和数组都是在这里在这里分配内存。
是垃圾回收器的主要工作空间因此也称为GC堆。
堆是各个线程的共享区域
5.方法区
方法区用于存储已经被虚拟机加载的类信息,常量,静态变量,等数据
二、创建对象的过程
可以简单的分成两部分,加载类信息和创建对象。包括
1.类加载检查:
检查类是否被加载,解析,初始化过。如果没有,必须先加载再创建对象。
2.分配内存
为新生对象分配内存,所需大小在类加载完毕后即可确定,有两种分配方式。
指针碰撞式:当堆内存规整时使用,
空闲列表式:当内存不规整时使用
内存规整与否由垃圾回收器是否带有压缩功能决定
3.初始化零值
虚拟机将分配到的内存空间都初始化为零值。
4.设置对象头
虚拟机对对象进行必要的设置,包括这个对象是哪个类的实例,如何才能找到类的元数据信息,对象的哈希码,对象的GC分代年龄。
5.执行init方法
执行init方法,将对象按照程序员的意愿进行初始化。
三、对象的访问方式
对象的访问方式由虚拟机实现而定,目前主流的访问方式有 “使用句柄”和“直接指针”两种。
1.使用句柄,
如果是使用句柄的方法,那么堆内存中会开辟一块内存来作为句柄池,reference中存储的是句柄的地址,句柄中存储的是对象实例数据与类型数据的地址
这样做的好处是,对象被移动时只会改变句柄中的实例数据指针,reference中的句柄地址稳定不用修改.
2.直接访问,
如果使用的是直接访问,那么reference中存储的直接是对象的地址值.
这样做的好处是速度快,节省了一次指针定位的时间开销
出处:https://blog.csdn.net/qq_34337272/article/details/81875700