基础之重蹈覆辙

MESI缓存一致性协议

前🌽:

高速缓存底层数据结构:拉链散列表的结构

bucket - cache entry - tag主内存地址 cache line缓存数据 flag缓存行状态

cache line64字节 有效引用主内存地址,连续的相邻的数据结构 读取特别快

处理器读写高速缓存,据变量名执行内存地址解码的操作,解析出:

index 定位到拉链散列表中的某个bucket

tag定位 cache entry

offerset定位变量在 cache line位置

每核CPU有自己的L1 L2缓存,多线程编程 另一核想访问当前核内L1 L2数据?

mesi缓存不命中且数据块在另一个缓存时,容许缓存到缓存的数据复制:高效

状态转换

初始 :没有加载任何数据,I

本地写local write :本地处理器写数据到I的缓存行,M

本地读local read:本地处理器读I状态缓存行,此缓存没有数据可读

其他处理器缓存里没有此行数据,从内存加载数据到缓存行 设成E,只有me有

其他处理器有,此缓存行S(M状态的缓存行 由本地处理器写入/读出 状态不改)

远程读:c1 c2,c2需要c1缓存行数据,c1通过内存控制器memory controller发送c2,内存从总线存该份数据,c2将相应缓存行=S

远程写 :c2得到c1数据,c2发RFO(request for owner) 拥有该份数据的权限,其他处理器相应缓存行=I 无权再操作该份数据,性能消耗大,什么情况下出现FRO,修改共享数据的时候

两个线程修改同一个cache line中不同的数据,轮番发送RFO占用缓存行拥有权,切换I ,而且其他线程读取此行数据L1 L2都是失效的,L3最新但是读取耗性能 更别说跨槽读 only内存上加载

涉及到一个伪共享问题,解决:让不同线程操作对象处于不同缓存行--》缓存行填充

缓存行64字节,java对象头markwork固定8字节(32)/12字节(64压缩不压16),填充6个无用长整形6*8字节,不同对象不同缓存行

对象头与锁状态

对象头:hotspot

markWord:存储hashCode,分代年龄 锁标志位 ,非固定结构 存储尽量多数据,动态调整,对象的状态复用自己存储空间,随着锁标志位的变化而变化

Klass point元数据指针,通过指针确定对象是哪个类的实例

无锁:25bit存对象头hashcode,4bit存放对象分代年龄,1bit是否偏向锁的标识位 2bit锁标识位01

偏向锁:25bit空间中 23bit存放线程id 2bit存放epoch 4bit分代年龄 1bit是否偏向锁标识 0无锁 1偏向锁 锁标识位01

轻量级锁:30bit指向栈中锁记录的指针 2bit锁标识位:00

重量级锁:30bit指向重量级锁的指针,2bit存放锁标识位:11

GC标记:开辟30bit内存空间没有用上,2bit存放锁标志位11

内存分配:

age_bits:分代回收的标识,4字节

lock_bits:锁标志位,2字节

biased_lock_bits:是否偏向锁标识,1字节

max_hash_bits:无锁计算的hashcode占用字节数量,32位虚拟机 32-4-2-1= 25,64位64-4-2-1=57,25字节不用,hashcode占用31位

hash_bits:64位虚拟机,最大字节>31,取31 否则真实字节数

cms_bits:不是64位虚拟机占0byte,否则1byte

epoch_bits:epoch所占有字节大小,2字节

monitor:

线程私有的数据结构,每个线程都有一个可用monitor record列表 全局可用列表;每个被锁住的对象都会和一个monitor关联,monitor有owner字段存放拥有锁的线程的唯一标识

synchronized通过对象内部监视器锁monitor实现,本质依赖底层操作系统mutex lock互斥锁实现,操作系统实现线程间切换需要用户态转换到核心态,成本高,状态转换时间长:重量级锁

-XX:-UseBiasedLocking=false来禁用偏向锁

锁分类

无锁:循环内进行修改,不断尝试修改共享资源, 只有一个能修改成功 其他循环重试

偏向锁 :第一次synchronized,修改对象头锁标志位:偏向锁,执行完同步代码块后 第二次达到同步代码块 线程会判断持有锁是不是自己,是 则正常执行

线程访问同步代码块,markwork获取线程id CAS判断

撤销:等待全局安全点,没有字节码执行,暂停拥有偏向锁的线程,判断对象是否被锁定,对象头无锁状态01或00轻量级锁 撤销偏向锁

轻量级锁:关闭偏向锁/多个线程竞争偏向锁导致锁升级

锁竞争:线程尝试获取锁,该锁被占有,自旋 等待释放,cas修改对象头锁标志位

长时间自旋非常耗费资源,其他线程原地空耗cpu 执行不了有效任务:忙等

重量级锁:忙等有限度(计数器记录自旋次数10),锁竞争严重达到最大自旋次数的线程,轻量级转重量级CAS修改锁标志位不改线程id,后续线程发现是重量级锁 将自己挂起 等待唤醒

控制权交给操作系统,操作系统负责线程间调度和线程状态变更

并发基础++-CSDN博客

锁的五种状态

JVM:

cpu使用过高:方法导致

磁盘IO高:栈

内存过高:堆

GC:堆

YGC:eden区满了

动态分配规则:

相同age的对象的大小之和 > 1/2的存活区大小 sum(age.mem)>=1/2S0, >=age的对象挪动到老年代

redis缓存三大问题:

缓存穿透:不存在的数据,布隆过滤器或者黑白名单 缓存预热

缓存击穿 :热点数据失效,互斥锁/分布式锁 预热失效时快速刷新缓存

互斥锁/分布式锁:

永不过期:redis不设置过期时间,后台异步线程刷新缓存

存过期时间,快过期去更新

缓存雪崩:大量数据同时失效,随机过期时间 限流 预热 自动刷新

多级缓存 / 缓存预热 / 限流

数据一致性问题

不重要业务:先更数据库再删缓存(暂时性不一致)

缓存更新成功返回,异步线程去更新数据库(缓存挂了,数据丢失)

双写:先写myql在写redis,事务

数据同步:定期mysql同步到redis,定时任务 变更数据时触发同步

实时数据流:实时数据流 消息队列 ,mysql变更同步到redis

设计模式

工厂模式:

创建对象的接口,具体的对象创建延迟到子类

单例模式:

饿汉式:类加载时初始化,线程安全

懒汉式:用到的时候实例对象并赋值属性 返回

反射:强制访问

序列化破坏单例:序列化写入磁盘 使用时从磁盘读取对象反序列化

反序列化对象重新分配内存,readResolve解决了被破坏的问题

枚举单例模式:无序列号问题 不能被反射获取

百度安全验证

daj

学会这10种定时任务,我有点飘了_crond

这个有人知道吗?什么位图定时任务?

:的ack

ack=0 不等待确认

ack=1 leader确认入盘,默认

ack=all,等待isr所有的副本确认

消息丢失:

生产者producer :默认send异步发送,改成get同步发送,等待被broker成功接收再发下一条

或者注册回调函数:重试直到成功

重试机制 :网络/broker故障,尝试重试 设置acks

性能:客户端使用buffer累积一定数量才发送

ISR:与leader保持同步到副本列表,被isr列表副本成功接收才消息被成功存 储

broker:数据持久化到磁盘

默认写入pageCache后向producer响应

改为同步刷盘 flush.messages写*条fsync,flush.ms*毫秒fsync刷盘

副本机制:分区配副本

消费者consumer:关闭自动提交offset,消费逻辑幂等性

默认:自动提交 开始poll先看是否auth.commit.interval.ms满足先提上一批消息的位移再处理下一批消息:重复消费

enable.auto.commit=false手动提交,消费完准备提 宕机了 重启再次消费:至少消费一次

spring-kafka@KafkaListener enable.auth.commit=false ackmode=manual手动提交

Kafka的消息可靠性(防止消息丢失)_flush.messages kafka-CSDN博客

百度安全验证

相关推荐
火烧屁屁啦17 分钟前
【JavaEE进阶】初始Spring Web MVC
java·spring·java-ee
w_312345430 分钟前
自定义一个maven骨架 | 最佳实践
java·maven·intellij-idea
岁岁岁平安33 分钟前
spring学习(spring-DI(字符串或对象引用注入、集合注入)(XML配置))
java·学习·spring·依赖注入·集合注入·基本数据类型注入·引用数据类型注入
武昌库里写JAVA36 分钟前
Java成长之路(一)--SpringBoot基础学习--SpringBoot代码测试
java·开发语言·spring boot·学习·课程设计
Q_192849990643 分钟前
基于Spring Boot的九州美食城商户一体化系统
java·spring boot·后端
张国荣家的弟弟1 小时前
【Yonghong 企业日常问题 06】上传的文件不在白名单,修改allow.jar.digest属性添加允许上传的文件SH256值?
java·jar·bi
ZSYP-S1 小时前
Day 15:Spring 框架基础
java·开发语言·数据结构·后端·spring
yuanbenshidiaos1 小时前
C++----------函数的调用机制
java·c++·算法
是小崔啊2 小时前
开源轮子 - EasyExcel01(核心api)
java·开发语言·开源·excel·阿里巴巴
黄公子学安全2 小时前
Java的基础概念(一)
java·开发语言·python