JVM垃圾回收
Java 不用“手动管理”内存回收,JVM 是有专门的线程在做这件事情。当我们的内存空间达到一定条件时,会自动触发。这个过程就叫作 GC,负责 GC 的组件,就叫作垃圾回收器。
JVM 规范并没有规定垃圾回收器怎么实现,它只需要保证不要把正在使用的对象给回收掉就可以。在现在的服务器环境中,经常被使用的垃圾回收器有 CMS 和 G1,但 JVM 还有其他几个常见的垃圾回收器。
按照语义上的意思,垃圾回收,首先就需要找到这些垃圾,然后回收掉。但是 GC 过程正好相反,它是先找到活跃的对象,然后把其他不活跃的对象判定为垃圾,然后删除。所以垃圾回收只与活跃的对象有关,和堆的大小无关。
标记(Mark)垃圾回收的第一步,就是找出活跃的对象。GC 过程是逆向的。
根据 GC Roots 遍历所有的可达对象,这个过程,就叫作标记。
如图所示,圆圈代表的是对象。绿色的代表 GC Roots,红色的代表可以追溯到的对象。可以看到标记之后,仍然有多个灰色的圆圈,它们都是被回收的对象。
清除(Sweep)清除阶段就是把未被标记的对象回收掉。
但是这种简单的清除方式,有一个明显的弊端,那就是碎片问题。
比 ...
Mysql Explain之type详解
EXPLAIN是什么MySQL 提供了一个 EXPLAIN 命令, 它可以对 SQL 语句进行分析, 并输出 SQL 执行的详细信息, 以供开发人员针对性优化.
例如分析一条 SELECT 语句 sql EXPLAIN SELECT * FROM user WHERE id = 1
EXPLAIN 结果中的type字段
Tips:常见的扫描方式 system:系统表,少量数据,往往不需要进行磁盘IO const:常量连接 eq_ref:主键索引(primary key)或者非空唯一索引(unique not null)等值扫描 ref:非主键非唯一索引等值扫描 range:范围扫描 index:索引树扫描 * ALL:全表扫描(full table scan)
type扫描方式由快到慢排序system > const > eq_ref > ref > range > index > ALL
1.system
上例中,从系统库mysql的系统标proxies_priv里查询数据,这里的数据在Mysql服务启动时候已经加载在内存中,不需要进行磁 ...
IO模型
本文讨论的背景是Linux环境下的network IO。本文最重要的参考文献是Richard Stevens 的 “UNIX? Network Programming Volume 1, Third Edition: The Sockets Networking ”,6.2节“I/O Models ”,Stevens在这节中详细说明了各种IO的特点和区别,如果英文够好的话,推荐直接阅读。Stevens的文风是有名的深入浅出,所以不用担心看不懂。本文中的流程图也是截取自参考文献。
Stevens在文章中一共比较了五种IO Model:
* blocking IO
* nonblocking IO
* IO multiplexing
* signal driven IO
* asynchronous IO
由于signal driven IO在实际中并不常用,所以主要介绍其余四种IO Model。
再说一下IO发生时涉及的对象和步骤。对于一个network IO (这里我们以read举例),它会涉及到两个系统对象,一个是调用这个IO的process (or thread),另一个 ...
TLAB简介
一、Java对象的内存分配过程如何保证线程安全的?因为堆是线程之间共享的,如果在并发场景中,两个线程先后把对象的引用指向了同一个内存区域,怎么办?
为了解决这个并发问题,对象的内存分配过程就必须进行同步控制,但是,无论使用哪种方案(有可能是CAS),都会影响内存的分配效率。然而对于 Java 来说对象的分配是高频操作。
由此 HotSpot 虚拟机采用了这个方案:每个线程在 Java 堆中预先分配一小块内存,然后在给对象分配内存的时候,直接在自己的这块”私有“内存中进行分配,当这部分用完之后,再分配新的”私有“内存。
这种方案被称之为 TLAB 分配。这部分 buffer 是从堆中划分出来的,但是本地线程独享的。
二、什么是 TLABTLAB 是虚拟机在内存的 eden 区划分出来的一块专用空间,是线程专属的。在启用 TLAB 的情况下,当线程被创建时,虚拟机会为每个线程分配一块 TLAB 空间,只给当前线程使用,这样每个线程都单独拥有一个空间,如果需要分配内存,就在自己的空间上分配,这样就不存在竞争的情况,可以大大提高分配效率。
所以说,因为有了 TLAB 技术,堆内存并不是完完全全 ...
使用canal实现MySQL和ES数据同步
canal简介canal主要用途是对MySQL数据库增量日志进行解析,提供增量数据的订阅和消费,简单说就是可以对MySQL的增量数据进行实时同步,支持同步到MySQL、Elasticsearch、HBase等数据存储中去。
canal工作原理canal会模拟MySQL主库和从库的交互协议,从而伪装成MySQL的从库,然后向MySQL主库发送dump协议,MySQL主库收到dump请求会向canal推送binlog,canal通过解析binlog将数据同步到其他存储中去。
canal使用canal的各个组件的用途各不相同,下面分别介绍下:canal-server(canal-deploy):可以直接监听MySQL的binlog,把自己伪装成MySQL的从库,只负责接收数据,并不做处理。canal-adapter:相当于canal的客户端,会从canal-server中获取数据,然后对数据进行同步,可以同步到MySQL、Elasticsearch和HBase等存储中去。canal-admin:为canal提供整体配置管理、节点运维等面向运维的功能,提供相对友好的WebUI操作界面,方便更多 ...
使用canal和RabbitMQ实现缓存数据同步
1. 缓存更新策略1.1 需求分析当tb_ad(广告)表的数据发生变化时,更新Redis中的广告数据。
1.2 实现思路(1)修改数据监控微服务,监控tb_ad表,当发生增删改操作时,提取position值(广告位置key),发送到RabbitMQ
(2)从RabbitMQ中提取消息,通过OkHttpClient调用ad_update来实现对广告缓存数据的更新。
1.3 代码实现1.3.1 发送消息到mq(1)在RabbitMQ管理后台创建队列 ad_update_queue ,用于接收广告更新通知
(2)引入RabbitMQ起步依赖
<dependency>
<groupId>org.springframework.amqp</groupId>
<artifactId>spring-rabbit</artifactId>
</dependency>
(3)配置文件application.properties 添加内容
spring.RabbitMQ.host=192.168.200.128
...
线段树
线段树(Segment Tree)几乎是算法竞赛最常用的数据结构了,它主要用于维护区间信息(要求满足结合律)。与树状数组相比,它可以实现 O(log n) 的区间修改,还可以同时支持多种操作(加、乘),更具通用性。
接下来我们用这道模板题为例,看看线段树是怎么维护区间和这一信息的。
(洛谷P3372 【模板】线段树 1)
题目描述如题,已知一个数列,你需要进行下面两种操作:1.将某区间每一个数加上x2.求出某区间每一个数的和输入格式第一行包含两个整数N、M,分别表示该数列数字的个数和操作的总个数。第二行包含N个用空格分隔的整数,其中第i个数字表示数列第i项的初始值。接下来M行每行包含3或4个整数,表示一个操作,具体如下:操作1: 格式:1 x y k 含义:将区间[x,y]内每个数加上k操作2: 格式:2 x y 含义:输出区间[x,y]内每个数的和输出格式输出包含若干行整数,即为所有操作2的结果。
线段树的建立线段树是一棵平衡二叉树。母结点代表整个区间的和,越往下区间越小。注意,线段树的每个节点都对应一条线段(区间),但并不保证所有的线段(区间)都是线段树的节点,这两者应当区 ...
Caffeine原理及简单实践
1 简介Caffeine 是基于Java 8 开发的、提供了近乎最佳命中率的高性能本地缓存组件,Spring5 开始不再支持 Guava Cache,改为使用 Caffeine。
下面是Caffeine 官方测试报告。
由上面三幅图可见:不管在并发读、并发写还是并发读写的场景下,Caffeine 的性能都大幅领先于其他本地开源缓存组件。
本文先介绍 Caffeine 实现原理,再讲解如何在项目中使用 Caffeine 。
2 Caffeine 原理2.1 淘汰算法2.1.1 常见算法对于 Java 进程内缓存我们可以通过 HashMap 来实现。不过,Java 进程内存是有限的,不可能无限地往里面放缓存对象。这就需要有合适的算法辅助我们淘汰掉使用价值相对不高的对象,为新进的对象留有空间。常见的缓存淘汰算法有 FIFO、LRU、LFU。
FIFO(First In First Out):先进先出。
它是优先淘汰掉最先缓存的数据、是最简单的淘汰算法。缺点是如果先缓存的数据使用频率比较高的话,那么该数据就不停地进进出出,因此它的缓存命中率比较低。
LRU(Least Recently ...
Paxos协议和Raft协议
Paxos协议Paxos协议是一种用于分布式系统中实现一致性的共识算法。它由Leslie Lamport于1990年提出,是目前广泛应用于分布式计算领域的重要算法之一。
Paxos协议解决了分布式系统中的一致性问题,即在面对节点故障、网络延迟和消息丢失等情况下,如何确保节点达成一致的共识。
Paxos协议的核心思想是基于一个提议(proposal)的方式进行节点之间的通信和协商。协议中的参与者分为提议者(proposer)和接受者(acceptor)。节点通过提议者向接受者发出提案,并经过多轮的消息交互来达成一致。
Paxos协议的主要过程可以简要概括如下:
提案阶段(Prepare Phase):提议者向接受者发送一个编号为N的提案请求,要求接受者不再接受编号小于N的提案。
接受阶段(Accept Phase):如果接受者接收到了编号为N的提案请求,并且当前没有接受过更大编号的提案,那么它会接受该提案。
学习阶段(Learn Phase):一旦一个提案被大多数节点接受,它就被确定下来,并可以在系统中进行执行。
Paxos协议通过多轮的消息交互来保证节点之间达成共识,即使在网 ...
分布式事务
1 基础概念1.1 什么是事务
什么是事务?举个生活中的例子:你去小卖铺买东西,“一手交钱,一手交货”就是一个事务的例子,交钱和交货必 须全部成功,事务才算成功,任一个活动失败,事务将撤销所有已成功的活动。 明白上述例子,再来看事务的定义:
事务可以看做是一次大的活动,它由不同的小活动组成,这些活动要么全部成功,要么全部失败。
1.2 本地事务
在计算机系统中,更多的是通过关系型数据库来控制事务,这是利用数据库本身的事务特性来实现的,因此叫数据 库事务,由于应用主要靠关系数据库来控制事务,而数据库通常和应用在同一个服务器,所以基于关系型数据库的 事务又被称为本地事务。
回顾一下数据库事务的四大特性 ACID:
A(Atomic):原子性,构成事务的所有操作,要么都执行完成,要么全部不执行,不可能出现部分成功部分失 败的情况。
C(Consistency):一致性,在事务执行前后,数据库的一致性约束没有被破坏。比如:张三向李四转100元, 转账前和转账后的数据是正确状态这叫一致性,如果出现张三转出100元,李四账户没有增加100元这就出现了数 据错误,就没有达到一致性。
...