JVM模型和GC算法
jvm8.x和之前版本有和区别!
- 内存 - 运行时数据区域[堆,虚拟机栈,本地方法栈,方法区,程序计数器]
- 线程隔离的 - 虚拟机栈,线程共享的堆和方法区
- jvm8内存模型改动
- 从堆剔除了永久代
- 新增了metaspace元空间,包括方法区,方法区包括常量池
对象搜索法 - 判断某个对象是否为垃圾对象
引用计数,如果该对象则计数+1,否则-1,如果为0,表示为垃圾对象,可以被回收
缺点: 不能解决循环引用
可达性分析对象 - 关键点必须要找GC Root,从根节点能够到达的对象 - 活着的对象,否则是垃圾对象
GC算法
标记 - 清除 - 产生垃圾碎片,简单
复制 - 新生代中From-To区域 - 浪费内存.适用的场景 - 对象存活率比较低.
标记 - 整理 - 老生代.适用存活率高.将活着的对象全部移到一端.
分代回收 - 将区域根据特点分成不同的区域 - 新生代[复制]和老生代[标记整理]不同的区域采用不同的算法
总结:新new出来的对象会进入到新生代中的伊甸园区域,然后经过GC检测之后,将活着的对象移动到From区域.
经过GC15次检测之后,仍然存活的对象才会移动到老年代中. [8:1:1]
redis的缓存穿透,击穿,雪崩
- 缓存穿透 - 数据库/redis中都不存在的数据.
- 缓存击穿[在同一个时刻,多个线程请求的是同一行记录]是指缓存中没有但数据库中有的数据(一般是缓存时间到期),这时由于并发用户特别多,同时读缓存没读到数据,又同时去数据库去取数据,引起数据库压力瞬间增大,造成过大压力。
- 缓存雪崩 - 缓存雪崩是指缓存中数据大批量到过期时间,而查询数据量巨大,引起数据库压力过大甚至down机。和缓存击穿不同的是, 缓存击穿指并发查同一条数据,缓存雪崩是不同数据都过期了,很多数据都查不到从而查数据库。
redis和mysql如何进行数据同步/一致性
1-1. 不是特别完美的解决 - 延时双删策略
public void update(User user){ redis.delKey(key);//删除缓存 db.updateData(data);//更新缓存 Thread.sleep(500);//睡了一会 redis.delKey(key);//再删除一次缓存 }
1. 先写库,再直接删缓存 - 不合理的原因 2. 先删缓存 - 再写库 - 不合理的原因 3. 延时双删策略 - 为什要睡 - 为了读到脏数据的线程,把这个脏数据放入到redis中 - 等读线程执行完毕之后.
1-2. 异步更新缓存(基于订阅binlog的同步机制)
第一步:开启binlog
-- 查看binlog是否开启 show variables like 'log_%';
第二步:my.ini文件
[mysqld] # 开启 binlog log_bin=mysql-bin # 选择 ROW 模式 binlog-format=ROW # 配置 MySQL replaction 需要定义,不要和 canal 的 slaveId 重复 server_id=1
第三步:创建MySQL slave 的权限canal账户并且进行远程连接授权
CREATE USER canal IDENTIFIED BY 'canal'; GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'canal'@'%'; -- GRANT ALL PRIVILEGES ON *.* TO 'canal'@'%' ; FLUSH PRIVILEGES;
第三步:重启mysql服务
Linux: systemctl restart mysqld Window: net stop mysql; net start mysql;
类加载器
物理分页和逻辑分页
上一篇

2021-10-26
下一篇

2021-10-26