Mysql索引优化实战
不容易理解的综合例子示例表
12345678910111213141516171819202122232425262728CREATE TABLE `employees` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(24) NOT NULL DEFAULT '' COMMENT '姓名', `age` int(11) NOT NULL DEFAULT '0' COMMENT '年龄', `position` varchar(20) NOT NULL DEFAULT '' COMMENT '职位', `hire_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '入职时间', PRIMARY KEY (`id`), KEY `idx_name_age_position` (`name`,`age`,`po ...
全面理解mysql架构
Mysql快速安装官方文档:https://dev.mysql.com/doc/refman/8.0/en/installing.html
Centos7安装mysql8
Docker 安装 MySQL8.0
一条SQL查询语句是如何执行的我们经常说,看一个事儿千万不要直接陷入细节里,你应该先鸟瞰其全貌,这样能够帮助你从高维度理解问题。同样,对于 MySQL 的学习也是这样。平时我们使用数据库,看到的通常都是一个整体。
比如,你有个最简单的表,表里有一个 ID 字段,在执行下面这个查询语句时:我们看到的只是输入一条语句,返回一个结果,却不知道这条语句在 MySQL 内部的执行过程。
1mysql> select * from user where id=10;
下面是 MySQL 的基本架构示意图,从中我们可以清楚地看到 SQL 语句在 MySQL的各个功能模块中的执行过程。
select 执行过程客户端连接工具(Navacat、SQLyog、JDBC)都归纳为MySQL客户端(Client),主要用于发送执行sql语句的请求。
服务端大体来说,MySQL 服务端可以分为 Ser ...
JDK17 新特性梳理
为什么是JDK17 “你发任你发,我用 Java8”。虽然业界现在对于 JDK8 后每半年更新一次的 JDK 新版本都保持着比较谨慎的态度,但是 JDK17是一个 Java 程序员不得不去关注的新版本。 最直观的原因是,作为现代 Java 应用基石的 Spring 和 SpringBoot ,都在新版本中走出了抛弃 JDK8,支持 JDK17 的这一步。
你或许不一定需要像技术极客一样去紧追 JDK 各种令人眼花缭乱的最新特性,但是 JDK17 却是每个 Java 程序员必须走出的下一个里程碑。不光是因为 JDK17 是 JDK8 后一个重要的 LTS 长期支持版本,更是因为在应用生态构建方面,JDK17 会比之前的 JDK11 更加成熟。
个人觉得,跳过 JDK11,直接入手 JDK17,对 JDK8 时代的程序员来说是一个比较实惠的选择。而至于后续的 JDK21 版本,除了虚拟线程比较亮眼外,其他特性相比 JDK17,感觉不痛不痒。因此,接下来,楼兰将在 JDK8 的基础上,带你全面认识一下 JDK17。
语法层面新特性1、文本块文本块功能,文本块指多行的字符串,使用 ...
垃圾收集器ZGC深度剖析
引言对于Java 程序员来说,JVM 帮助我们做了很多事情。JVM是虚拟机,能够识别字节码,就是class文件或者你打包的jar文件,运行在操作系统上。JVM帮我们实现了跨平台,你只需要编译一次,就可以在不同的操作系统上运行,并且效果是一致的。
在Java中你使用对象,使用内存,不用担心回收,只管new对象就行了,不用管垃圾的回收。
因为Java当中是自动化的垃圾回收机制。JVM有专门的垃圾回收器,把垃圾回收这件事给干了。
ZGC出现背景但是对于Java的项目来说,JVM进行垃圾回收会有一个很大的问题,就是STW。什么是STW,STW的全称是StopTheWorld
Java项目中,如果JVM要进行垃圾回收,会暂停所有的业务线程,也就是项目中的线程,这样会导致业务系统暂停。
STW带来的问题手机系统(Android) 显示卡顿
Google 主导的 Android 系统需要解决的一大问题就是显示卡顿问题,通过对 GC 算法的不断演进,停顿时间控制在几个ms 级别。
所以这也是Android与苹果IOS系统竞争的一大利器。
证券交易系统实时性要求
证券交易系统主要就是买入、卖出,现在都 ...
Class常量池与运行时常量池
Class常量池可以理解为是Class文件中的资源仓库。 Class文件中除了包含类的版本、字段、方法、接口等描述信息外,还有一项信息就是常量池(constant pool table),用于存放编译期生成的各种字面量(Literal)和符号引用(Symbolic References)。
一个class文件的16进制大体结构如下图:
对应的含义如下,细节可以查下oracle官方文档
当然我们一般不会去人工解析这种16进制的字节码文件,我们一般可以通过javap命令生成更可读的JVM字节码指令文件:红框标出的就是class常量池信息,常量池中主要存放两大类常量:字面量和符号引用。
字面量字面量就是指由字母、数字等构成的字符串或者数值常量字面量只可以右值出现,所谓右值是指等号右边的值,如:int a=1 这里的a为左值,1为右值。在这个例子中1就是字面量。
1234int a = 1;int b = 2;int c = "abcdefg";int d = "abcdefg";
符号引用符号引用是编译原理中的概念,是相对于直接引用来说的。 ...
Arthas使用详解以及调优实战
Arthas详解Arthas 是 Alibaba 在 2018 年 9 月开源的 Java 诊断工具。支持 JDK6+, 采用命令行交互模式,可以方便的定位和诊断线上程序运行问题。Arthas 官方文档十分详细,详见:https://alibaba.github.io/arthas
Arthas使用场景得益于 Arthas 强大且丰富的功能,让 Arthas 能做的事情超乎想象。下面仅仅列举几项常见的使用情况,更多的使用场景可以在熟悉了 Arthas 之后自行探索。
是否有一个全局视角来查看系统的运行状况?
为什么 CPU 又升高了,到底是哪里占用了 CPU ?
运行的多线程有死锁吗?有阻塞吗?
程序运行耗时很长,是哪里耗时比较长呢?如何监测呢?
这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception?
我改的代码为什么没有执行到?难道是我没 commit?分支搞错了?
遇到问题无法在线上 debug,难道只能通过加日志再重新发布吗?
有什么办法可以监控到 JVM 的实时运行状态?
Arthas使用
1234# github下载arthaswget https ...
JVM调优工具详解及调优实战
Jmap此命令可以用来查看内存信息,实例个数以及占用内存大小
12jmap -histo 14660 #查看历史生成的实例jmap -histo:live 14660 #查看当前存活的实例,执行过程中可能会触发一次full gc
打开log.txt,文件内容如下:
num:序号
instances:实例数量
bytes:占用空间大小
class name:类名称,[C is a char[],[S is a short[],[I is a int[],[B is a byte[],[[I is a int[][]
堆信息
堆内存dump1jmap -dump:format=b,file=eureka.hprof 14660
也可以设置内存溢出自动导出dump文件(内存很大的时候,可能会导不出来)
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=./ (路径)
示例代码:
12345678910111213141516public class OOMTest { public stat ...
垃圾收集器G1&ZGC详情
G1收集器(-XX:+UseG1GC)G1 (Garbage-First)是一款面向服务器的垃圾收集器,主要针对配备多颗处理器及大容量内存的机器. 以极高概率满足GC停顿时间要求的同时,还具备高吞吐量性能特征.
G1将Java堆划分为多个大小相等的独立区域(Region),JVM目标是不超过2048个Region(JVM源码里TARGET_REGION_NUMBER 定义),实际可以超过该值,但是不推荐。
一般Region大小等于堆大小除以2048,比如堆大小为4096M,则Region大小为2M,当然也可以用参数”-XX:G1HeapRegionSize”手动指定Region大小,但是推荐默认的计算方式。
G1保留了年轻代和老年代的概念,但不再是物理隔阂了,它们都是(可以不连续)Region的集合。
默认年轻代对堆内存的占比是5%,如果堆大小为4096M,那么年轻代占据200MB左右的内存,对应大概是100个Region,可以通过“-XX:G1NewSizePercent”设置新生代初始占比,在系统运行中,JVM会不停的给年轻代增加更多的Region,但是最多新生代的占比不会超过60 ...
JVM对象创建与内存分配机制深度剖析
对象的创建对象创建的主要流程:类加载检查 –》 是否已加载类 –》分配内存 –》初始化–》设置对象头–》执行init 方法
1.类加载检查
虚拟机遇到一条new指令时,首先将去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已被加载、解析和初始化过。如果没有,那必须先执行相应的类加载过程。
new指令对应到语言层面上讲是,new关键词、对象克隆、对象序列化等。
2.分配内存
在类加载检查通过后,接下来虚拟机将为新生对象分配内存。对象所需内存的大小在类 加载完成后便可完全确定,为对象分配空间的任务等同于把 一块确定大小的内存从Java堆中划分出来。
这个步骤有两个问题:
1.如何划分内存。2.在并发情况下, 可能出现正在给对象A分配内存,指针还没来得及修改,对象B又同时使用了原来的指针来分配内存的情况。
划分内存的方法:
“指针碰撞”(Bump the Pointer)(默认用指针碰撞)如果Java堆中内存是绝对规整的,所有用过的内存都放在一边,空闲的内存放在另一边,中间放着一个指针作为分界点的指示器,那所分配内存就仅仅是把那个指针 ...
剖析jvm类加载机制与内存模型
一.加载机制类加载运行全过程当我们用java命令运行某个类的main函数启动程序时,首先需要通过类加载器把主类加载到JVM。
123456789101112131415public class Math { public static final int initData = 666; public static User user = new User(); public int compute() { //一个方法对应一块栈帧内存区域 int a = 1; int b = 2; int c = (a + b) * 10; return c; } public static void main(String[] args) { Math math = new Math(); math.compute(); } }
通过Java命令执行代码的大体流程如下:其中loadClass的类加载过程有如下几步:
加载 >> 验证 >> 准备 >> 解析 >&g ...