Android必学基础知识之Java内存结构

2020-03-24  本文已影响0人  怪兽来啦啦啦啦啦

前言

 JVM在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域。这些区域都有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而一直存在,有些区域则是依赖用户线程的启动和结束而建立与销毁。
 JVM所管理的内存包括以下几个区域:

JVM运行时数据区

1 程序计数器

定义

为什么是线程隔离的数据区?


2 Java虚拟机栈(VM Stack)

定义

为什么是线程隔离的数据区?

异常


3 本地方法栈(Native Method Stack)

定义

虚拟机异同


4 Java堆

定义

为什么是线程共享的?

异常


5 方法区

定义

异常


6 运行时常量

定义

什么是Class常量池?

运行期间能将新的常量放入池吗?

异常


7 直接内存

 直接内存不是虚拟机运行时数据区的一部分,也不是《Java虚拟机规范》中定义的内存区域,但是这部分也被频繁使用。
定义


8 对象

 以虚拟机HotSpot和常用的内存区域Java堆为例,探讨Java堆中对象分配、布局和访问的全过程。

8.1 创建对象

 创建对象分为以下 四步:
①当Java虚拟机遇到一条字节码new指令时,首先将去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并检查这个符号引用代表的类是否已被加载、解析和初始化过。如果没有,则必须执行相应的类加载过程。
②在类加载检查通过后,接下来虚拟机将为新生对象分配内存。有以下两种分配方法:

对象创建在虚拟机中时非常频繁的行为,但是在并发情况下也不是线程安全的。解决这个问题有两种可选方案:
一、虚拟机采用CAS配上失败重试的方法保证更新操作的原子性;
二、在每个线程Java堆中预先分配一小块内存,成为本地线程分配缓冲TLAB,哪个线程需要分配内存,就在哪个线程的TLAB上分配,只有TLAB用完需要分配新的TLAB才需要同步。

③内存分配完成之后,虚拟机必须将分配到的内存空间(不包括对象头)都初始化为零值,如果使用了TLAB,则可提前至TLAB分配时顺便进行。之后对对象进行必要的设置,这些信息将存放在对象的对象头之中。
④从虚拟机的视角看,一个新的对象已经产生。接着执行<init>()方法,按照程序员的意愿对对象进行初始化,一个真正的对象才算被完全构造出来。

8.2 对象的内存布局

 在HotSpot虚拟机里,对象在堆内存中国的存储布局可以划分为三个部分:对象头、实例数据和对其填充。
对象头
 HotSpot虚拟机对象的对象头部分包括两类信息。

实例数据

对齐填充

8.3 对象的访问定位

 《Java虚拟机规范》规定reference只是一个对象的引用,没有定义引用通过什么方式去定位和访问堆中对象的位置。主流的访问方式主要有使用句柄和直接指针两种:

句柄访问的优缺点

直接指针的优缺点

总结

上一篇下一篇

猜你喜欢

热点阅读