JVM(三),2021最新阿里Java面试流程

  • 静态成员变量赋默认值
3. resolution
  • classLoader源码中loadClass第二个参数boolean reolve,是否进行解析。

  • 将类、方法、属性等符号引用解析为直接引用。

  • 常量池中的各种符号引用解析为指针、偏移量等内存地址的直接引用

(符号引用:常量池中有一个类的名字,实际上这个类可能是在内存中的另一个片区域,被这个名字指向,当使用的时候我们写的字符指向这个名字,这个名字指向那一片真正的区域)

  • 解析就是让写的字符直接指向那一片类真正存在的内存空间。

二、Initializing

1. 调用类初始化代码,给静态成员变量赋初始值。
  • 上述总结:

  • 类:load - 默认值 - 初始值

  • object:new - 申请内存 - 默认值 - 初始值

在这里插入图片描述

  • 类初始化过程,0时申请空间并设默认值,4设初始值,7把引用指向空间。

  • 若发生指令重排则可能47颠倒,默认值后直接交给引用,volatile可避免。这也是DCL单例中

《一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》

【docs.qq.com/doc/DSmxTbFJ1cmN1R2dB】 完整内容开源分享

为什么成员变量需要加volatile。

三、JMM

1. 硬件层的并发优化基础知识(深入理解计算机系统 原书第三版 P421)
  • 存储器结构层次:

在这里插入图片描述

  • 运行速度 cpu > 内存 > 硬盘,cpu是内存100倍,是硬盘的100万倍(粗略)

  • 在运行时,cpu计算在找一个计算需要的数时一层一层往下去找,看目标位置,找到之后一层层向上运到寄存器。

  • L0到L2都是每个cpu自己内部独立的,从L3往下都是所有cpu共享的,L3区域在主板上。

  • 各层之间速度对比:

在这里插入图片描述

  • 老cpu使用总线锁来保证各个cpu中的数据一致,效率极低。

  • 现在用各种各样的一致性协议和总线锁相互配合:例如 MSI MESI MOSI…,intel cpu使用的MESI。

在这里插入图片描述

  • MESI Cache一致性协议简单大致内容:

  • 大致是每一个缓存的内容都加一个标记。

  • X跟主存内容相比如果更改过标记为Modified

  • 如果是这个cpu独享的,标记为Exclusive

  • 如果这个内容读的时候别的cpu也在读,标记为Shared

  • 如果这个内容读的时候别的cpu把他改了,标记为Invalid无效

  • 以上四种状态首字母合起来简称MESI

  • cache line 缓存行:

  • 读取缓存以cache line为基本单位,一般是64字节 4个位置。

在这里插入图片描述

  • 伪共享问题:xy两个数在一个缓存行,cpu1需要x则整个缓存行读取进来改了x,cpu2需要y则整个缓存行读取进来改了y,改完x之后cpu1通知2说这个缓存行我改过了你标记为无效,重新读一下xy整个缓存行,2改完2之后同样通知1重新读取。

  • 位于同一缓存行的两个不同数据,被两个不同cpu锁定,产生互相影响的伪共享问题。

  • 可以用对齐来解决,即每个需要的数放入不同缓存行,本缓存行其他位置用别的无用的数来填充满64字节,这样提升了效率,而空间多使用了一点点。

在这里插入图片描述

  • 如上图,声明7个long类型(8字节),7×8=56,然后声明需要的x变量,现在是8×8=64字节,y同理,这样xy就分开了,其他为填充的无用数据。

  • disruptor指针的源码实现有一段:,前面声明7个long类型(8字节),后面声明7个long,保证cursor不管跟前面的对齐还是后面的对齐,一定是自己在一个缓存行内,所以效率十分高。

在这里插入图片描述

  • 乱序问题:

  • Cpu为了提高指令执行效率,会在一条指令执行过程中(比如去内存读数据,因为cpu速度至少快内存100倍),cpu等待内存返回的值的同时进行下一条指令的执行,前提是两条指令没有依赖关系。

  • 写的时候,多个指令合并一起结果给内存中,原因还是内存太慢了,L2L3之间其实还有一个WCBuffer,合并写的缓存,放入一起交给内存。

  • WCBuffer一般只有4个字节,这个缓存实际上比L1 L2还要快,当这四个字节都满了才会把内容刷走,所以就有了合并写技术:

  • 假如有一个6字节的数据需要执行,一下把这6个字节挨个执行的速度远慢于3个字节执行,3个字节执行的速度(3个是因为执行的时候在这里插入图片描述,比如这样,b也占一个字节)

  • 因为3+3的话,先放一个3然后b占一个,wcbuffer直接满了就发车了,如果是直接扔6个,前4个进入了wcbuffer满了发车了,后两个存进来之后还得等两个其他的占上剩下的2字节才能发车,所以慢,所以手动分成两个缓存比直接扔给缓存然后顺序执行的效率高很多,也是相当于上述缓存行对齐的一种应用场景。

  • 特定情况下有序性保障:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值