架构师 3 期 3 班 -week9- 总结
数据库
主要组成部分
连接器
语法分析
词法分析及优化
执行计划
PrepareStatement 的优势
提高性能,提前将带占位符的 sql 生成 AST 语法树,以及词法分析优化,生成执行计划,在传入参数后直接按执行计划执行 sql
防止 sql 注入,由于提前生成了 AST 语法树及执行计划,不会因为传入的变量是一个或多个 sql 再去重新生成语法树,只会将传入的数据硬塞入执行计划,查处 nil
索引
mysql 使用 b+树做索引,b+树只有叶子结点记录数据的指针,非叶子结点只记录叶子结点的指针。
聚簇索引
聚簇索引是指索引树不止记录了索引,也记录数据。mysql 的主键索引就是聚簇索引,b+树的叶子结点记录着行数据。mysql 的数据存储文件就是一个以主键聚簇索引生成的 b+树。
非聚簇索引
非聚簇索引子结点记录的是聚簇索引(主键),使用非聚簇时,先查到非聚簇索引,再通过非聚簇索引查到的主键进行非聚簇索引查询数据,这个操作叫做回表
索引的注意事项
索引越多,增删数据操作的 b+树就越多,即越慢
索引越小,能存储的索引越多,查询效率越高
事务
数据库通过事务日志,来实现对事务的控制,要么全部成功,要么全部失败
事务日志的组成
LSN 按时间分配的全局唯一的事物日志序列号
TransID 事物的 id
PageID 被修复的数据存储的磁盘位置
PrevLSN 同一个事务中上一条操作的 LSN
UNDO 取消本次操作的方法
REDO 重复本次操作的方法
JVM 虚拟机的架构及原理
组成部分
类加载器 将类的字节码加载到方法区
运行期数据区 包括方法区、堆、栈及程序计数寄存器
执行引擎 负责将字节码转化成本地执行命令
通过 java 命令启动 jvm 虚拟机进程,jvm 虚拟机通过类加载器将类的字节码存入运行期数据区中的方法区,程序启动主线程执行 main 方法,为线程分配单独的栈和程序计数寄存器,程序计数寄存器记录当前线程在方法区中执行到什么位置。
执行引擎负责将 java 字节码转换成本地执行的指令,实现跨平台。
创建对象 new 出来的放在堆中,对象的引用即变量放在线程的栈中。
字节码执行流程
检查是否编译(热代码被 cache)
程序计数器+1
判断程序计数器是否超过阀值
超过阀值,编译成可执行的本地代码并 cache
未超过阀值,解释器解释成本地可执行代码
将本地可执行代码交给执行器执行
类加载器
jvm 的类加载器是分层加载的,如果顶层已经加载过了,则不需要从新加载,直接使用顶层加载的类即可
类加载器自顶向下
BootstrapClassloader 加载 jdk 核心的 rt.jar
ExtensionClassloader 加载 jdk 包下的 ext 下的 jar 包
ApplicationClassloader 加载应用程序 class 和依赖的 jar
UserDiyClassloader 自定义 classloader
自定义 classloader 的作用
类的隔离,同样类路径和类名相同,实现不同,可以通过自定义的加载器隔离加载
自定义加载逻辑,如类文件的来源,源码的加密等
运行时数据区
堆
整个虚拟机共享一块堆内存,对象的实例或者数组等都在堆中
栈
每个线程有自己的栈空间,存储对象的引用,程序的操作都在栈上完成
方法区
方法区中存放着类加载器加载的类的字节码、类的静态变量、常量池。实际上方法区也是堆的一部分。
程序计数寄存器
记录当前线程执行到哪一行字节码指令
JVM 垃圾回收机制
jvm 垃圾回收就是将堆中不在使用的内存释放出来
可达性分析
jvm 通过可达性分析来判断对象是否应该被回收
具体过程:从程序栈桢的变量、方法区静态变量出发,将这些变量引用的对象标记,再递归的标记这些对象引用的其他对象。标记完成后,所有未标记的对象就是可被 k 回收的垃圾对象。
垃圾回收的方法
清理
jvm 将未标记的对象置为空闲,在 jvm 需要内存时从空闲的内存中分配。
优点:效率高
缺点:内存碎片话,利用率低,很可能没有大的连续内存
压缩
jvm 将未标记的清除,将已标记的前移至头部
优点:内存使用率高,无碎片化
缺点:效率低
复制
将内存分成 2 块,将标记的复制到未使用的一块内存中,讲原来内存中的所用数据清除
以空间换时间
优点:效率高,内存不会碎片化
缺点:内存使用空间只有原来的一半
分代回收策略
jvm 启动参数
标准启动参数
所有版本 jdk 都支持
运行模式 -server -client
类加载路径 -cp
运行调试 -verbose
系统变量 -D
非标准启动参数
jvm 默认实现这些参数,但不保证所有 jvm 都实现,也不保证向后兼容
-Xms 初始堆大小
-Xmx 最大堆大小
-Xmn 新生代代小
-Xss 线程堆栈大小
非 Stable 参数
这类参数各个 jvm 实现可能不同,未来可能随时取消
-XX
并发编程优化
最佳启动线程数
启动线程数 = [任务执行时间/(任务执行时间-IO 等待时间)] * CPU 核心数
最佳线程数与 cpu 核心数成正比,和 IO 阻塞时间成反比
如果任务都是 cpu 计算密集型,线程数 = CPU 核心数即可,再多线程也要 cpu 来调度
如果任务是 IO 密集型,那么启动多线程可以提高并发吞吐量,改善系统性能
版权声明: 本文为 InfoQ 作者【zbest】的原创文章。
原文链接:【http://xie.infoq.cn/article/042f010806a172285de29fc9b】。未经作者许可,禁止转载。
评论