深入理解Java虚拟机 第二章 读书笔记

一、运行时数据区(Runtime Data Area)

1.程序计数器

①是一块较小的内存空间,它可以看做是当前线程所执行的字节码的行号指示器。在Java虚拟机的概念模型里,字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,它是程序控制流的指示器。

②线程私有,各条线程之间的计数器相互独立。

2.Java虚拟机栈

①虚拟机栈描述的是Java方法执行的线程内存模型,每个方法被执行时Java虚拟机都会同步创建一个栈帧,用于存储局部变量表(在编译期间完成分配)、操作数栈、动态连接、方法出口等信息。方法被调用时,入栈。方法执行结束时出栈。

②局部变量表包括:各数据基本类型、对象引用类型、返回值类型。

③变量槽:数据类型在局部变量表中以局部变量槽作为存储。一般一个数据占一个变量槽,long和double会占用两个。

④线程私有,生命周期与线程相同。

3.本地方法栈

①与虚拟机栈作用类似,本地方法栈是为了Native方法服务。

②HotSpot虚拟机会将本地方法栈和虚拟机栈合二为一。

③线程私有。

4.Java堆

①虚拟机中内存最大的一块。线程共享。在虚拟机启动时创建。存放对象的实例。

②垃圾收集器管理的内存区域,别称“GC堆”。

③堆可以处于物理上不连续的内存空间中,但在逻辑上视为连续的。

④可以固定大小、可以拓展大小(通过-Xmx和-Xms设定)

5.方法区

①线程共享

②存放class类、常量、静态变量、即时编译器编译后的代码缓存等数据。

③HotSpot在JDK8前方法区使用“永久代”的设计模式,JDK8后改为采用本地内存来实现。将字符串常量池、静态变量等移到了Java堆中。废弃永久代改成元空间。

5.1 运行时常量池

①方法区的一部分

②常量池表用于存放编译期生成的各种字面量与符号引用,在类加载后存放到运行时常量池中。

③运行时常量池相对于Class文件常量池的另外一个重要特征是具备动态性,并非预置入Class文件中常量池的内容才能进入方法区运行时常量池,运行期间也可以将新的常量放入池中。比如String的intern()方法。

5.2 直接内存

①本机直接内存

②在JDK1.4中新加入了NIO(New Input/Output)类,引入了一种基于通道和缓冲区的I/O方式,它可以使用Native函数库直接分配堆外内存,然后通过一个存储在Java堆里的DirectByteBuffer对象作为这块内存的引用进行操作,避免了在Java堆中和Native堆中来回复制数据,得以显著提高性能。

二、HotSpot虚拟机对象探秘

1.对象的创建

①当Java虚拟机遇到一条字节码new指令时,首先检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已被加载、解析和初始化。如果没有,必须先执行相应的类加载过程。

②Java堆是否规整取决于GC是否带有空间压缩整理的能力。Java堆内存开辟有以下两种分配方式。

指针碰撞:假设Java堆内存是绝对规整的,使用过的内存和未使用的内存各放一边,中间临界点放着一个指针,若需要开辟内存则指针往空闲空间挪动相应的大小。使用这种方式的GC有Serial、ParNew,简单高效。

空闲列表:假设Java堆内存不规整,虚拟机则需要规划一个内存使用记录表,分别记录使用过的内存和未使用的内存,若需要开辟内存则需要在内存记录表上寻找一块合适大小的内存并记录。使用这种方式的GC有CMS(Concurrent Mark Sweep)。

③对象的频繁创建引起的线程安全问题。

一是对分配内存空间的动作进行同步处理,采用CAS配上失败重试的方式保证更新操作的原子性。

二是把内存分配的动作按照线程划分在不同的空间之中进行。

2.对象的内存布局

2.1 对象头(Header)

①Mark Word :用于存储对象自身的运行数据,如哈希码、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等。数据长度为64bits,动态定义的数据结构,在极小的空间内存储尽量多的数据

②类型指针:即对象指向它的类型元数据的指针,通过这个指针来确定该对象是哪个类的实例。

2.2 实例数据部分

对象真正存储的有效信息。

2.3 对齐填充

无特殊含义、占位符。

3.对象的访问定位

Java程序会通过栈上的reference数据来操作堆上的具体对象,主流的访问方式有以下两种:

3.1 句柄访问

Java堆中将可能会划分出一块内存来作为句柄池,reference中存储的就是对象的句柄地址,而句柄中包含了对象实例数据与类型数据各自具体的地址信息。这种方式的好处是,reference中存储的是稳定的句柄地址,在对象被移动(被当做垃圾回收)时只会改变句柄中的实例数据指针,而reference本身不需要被修改。

3.2 直接指针访问

reference中存储的直接就是对象地址,不需要间接的开销,访问的速度更快。

目前HotSpot主要使用直接指针访问的方式进行对象访问。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值