写点什么

架构师训练营第九周总结

用户头像
_
关注
发布于: 2020 年 11 月 22 日

本周学习了数据库的架构原理,jvm 虚拟机架构原理,jvm 垃圾回收性能分析,java 代码优化的技巧以及原理,系统性能优化案例(实现一个秒杀系统)

数据库架构由连接器,语法分析器,语义分析和优化器,执行引擎组成

使用 prepareStatement 的优点:

1、数据库可以预处理 sql,效率更好一点

2、放置 sql 注入

数据存储使用的是 b+树结构

聚簇索引:

数据库记录和索引放在一起,如 mysql 的主键

非聚簇索引:

叶子节点存储的是主键,不是数据,通过非聚簇索引找到主键,再通过主键找到数据,也称为回表

为了增加查询效率,添加必要的常用查询的索引是有必要的,但是也不能一味地为了查询效率添加过多的索引,合理使用查询条件,减少不必要的索引,增加数据插入效率。

数据库事务特性:

原子性,一起成功或者一起失败

隔离性,两个事务同时运行,最终结果互不影响

持久性,一旦事务提交,数据就会保存在数据库中

一致性,合法的数据才能写入数据库


jvm 虚拟机原理

jvm 组成:方法区,堆,java 栈,程序计数器

java 通过编译器,生成字节码文件,通过 200 多个操作指令执行命令操作

字节码执行流程


类加载器的双亲委派模型

低层次的当前类加载器,不能覆盖更高层次类加载器已经加载的类。如果低层次的类加载器想加载一个未知类,需要上级类加载器确认,只有当上级类加载器没有加载过这个类,也允许加载的时候,才让当前类加载器加载这个未知类。


自定义类加载器

1、加载同一个类的不同版本

2、从其他地方加载类文件

3、加载自定义的加密字节码,在 classloader 中解密


堆 &栈

堆:每个 JVM 实例唯一对应一个堆。应用程序在运行中所创建的所有类实例或数组都放

在这个堆中,并由应用所有的线程共享。

堆栈:JVM 为每个新创建的线程都分配一个堆栈。也就是说,对于一个 Java 程序来说,

它的运行就是通过对堆栈的操作来完成的。

Java 中所有对象的存储空间都是在堆中分配的,但是这个对象的引用却是在堆栈中分配,

也就是说在建立一个对象时从两个地方都分配内存,在堆中分配的内存实际建立这个对

象,而在堆栈中分配的内存只是一个指向这个堆对象的引用而已。


方法区 &程序计数器

方法区主要存放从磁盘加载进来的类字节码,而在程序运行过程中创建的类实例则存放

在堆里。程序运行的时候,实际上是以线程为单位运行的,当 JVM 进入启动类的 main

方法的时候,就会为应用程序创建一个主线程,main 方法里的代码就会被这个主线程执

行,每个线程有自己的 Java 栈,栈里存放着方法运行期的局部变量。而当前线程执行

到哪一行字节码指令,这个信息则被存放在程序计数寄存器。



Java(线程)栈

所有在方法内定义的基本类型变量,都会被每个运行这个方法的线程放入自己的栈中,

线程的栈彼此隔离,所以这些变量一定是线程安全的。


线程工作内存 & volatile

Version:0.9 StartHTML:0000000105 EndHTML:0000000456 StartFragment:0000000141 EndFragment:0000000416

JVM 的垃圾回收

Version:0.9 StartHTML:0000000105 EndHTML:0000000459 StartFragment:0000000141 EndFragment:0000000419

JVM 分代垃圾回收

Version:0.9 StartHTML:0000000105 EndHTML:0000000462 StartFragment:0000000141 EndFragment:0000000422

JVM 垃圾回收器算法

Version:0.9 StartHTML:0000000105 EndHTML:0000000470 StartFragment:0000000141 EndFragment:0000000430

G1 垃圾回收内存管理机制


Version:0.9 StartHTML:0000000105 EndHTML:0000000453 StartFragment:0000000141 EndFragment:0000000413


Java 启动参数

Version:0.9 StartHTML:0000000105 EndHTML:0000005805 StartFragment:0000000141 EndFragment:0000005765

标准参数,所有的 JVM 实现都必须实现这些参数的功能,而且向后兼容

• 运行模式 -server,-client

• 类加载路径 -cp,-classpath

• 运行调试 –verbose

• 系统变量 –D

非标准参数, 默认 jvm 实现这些参数,但不保证所有 JVM 实现都实现,且不保证向后兼容

-Xms 初始堆大小

-Xmx 最大堆大小

-Xmn 新生代大小

-Xss 线程堆栈大小

非 Stable 参数, 此类参数各个 jvm 实现会有所不同,将来可能会随时取消

-XX:-UseConcMarkSweepGC 启用 CMS 垃圾回收


Version:0.9 StartHTML:0000000105 EndHTML:0000001810 StartFragment:0000000141 EndFragment:0000001770

JVM 性能诊断工具

基本工具:JPS ,JSTAT,JMAP,JSTACK

集成工具: JConsole,JVisualVM


Version:0.9 StartHTML:0000000105 EndHTML:0000005853 StartFragment:0000000141 EndFragment:0000005813

JPS

JPS 用来查看 host 上运行的所有 Java 进程的 pid(jvmid),一般情况下使用这个工具

的目的只是为了找出运行的 JVM 进程 ID,即 lvmid,然后可以进一步使用其它的工具来

监控和分析 JVM

常用的几个参数:

• -l 输出 Java 应用程序的 main class 的完整包

• -q 仅显示 pid,不显示其它任何相关信息

• -m 输出传递给 main 方法的参数

• -v 输出传递给 JVM 的参数。在诊断 JVM 相关问题的时候,这个参数可以查看 JVM 相关参

数的设置


Version:0.9 StartHTML:0000000105 EndHTML:0000004271 StartFragment:0000000141 EndFragment:0000004231

JSTAT

JSTAT( “Java Virtual Machine statistics monitoring tool” )是 JDK 自带的一个轻量级

小工具。主要对 Java 应用程序的资源和性能进行实时的命令行的监控,包括了对 Heap

size 和垃圾回收状况的监控。

语法结构如下:jstat [Options] vmid [interval] [count]

• Options -- 选项,我们一般使用 - gcutil 查看 gc 情况

• vmid -- VM 的进程号,即当前运行的 Java 进程号

• interval-- 间隔时间,单位为毫秒

• count -- 打印次数,如果缺省则打印无数次



Version:0.9 StartHTML:0000000105 EndHTML:0000003179 StartFragment:0000000141 EndFragment:0000003139

JMAP

JMAP 是一个可以输出所有内存中对象的工具,甚至可以将 VM 中的 heap,以二进制输

出成文本。

使用方法

• jmap -histo pid>a.log 可以将其保存到文本中去,在一段时间后,使用文本对比工具,可以

对比出 GC 回收了哪些对象。

• jmap -dump:format=b,file=f1 PID 可以将该 PID 进程的内存 heap 输出出来到 f1 文件里。


jstack

jstack 可以查看 JVM 内的线程堆栈信息



Java 代码优化


合理并谨慎使用多线程

启动线程数 = [任务执行时间 / (任务执行时间 - IO 等待时间)] * CPU 内核数


竞态条件与临界区

临界区中适当使用同步可以避免静态条件


Java 线程安全

1、使用方法局部变量

2、方法局部对象的引用,创建的对象不会逃逸出该方法

3、对象存储堆上,两个线程同时更新这个对象,那么这个对象就不是线程安全的


ThreadLocal

不同线程拥有自己的内部变量;实现原理,根据不同的线程存储不同的对象


Java 内存泄漏

不再使用的对象却长期占用线程


需要我们能合理使用线程池和对象池

复用线程或对象资源,避免在程序的生命期中创建和删除大量对象

池管理算法(记录哪些对象是空闲的,哪些对象正在使用)

对象内容清除(ThreadLocal 的清空)使用合适的 JDK 容器类(顺序表,链表,Hash)


LinkList 和 ArrayList 的区别及适用场景

HashMap 的算法实现及应用场景


使用 concurrent 包,ConcurrentHashMap 和 HashMap 的线程安全特性有什么不同?

缩短对象生命周期,加速垃圾回收

1、减少对象驻留内存的时间

2、在使用时创建对象,用完释放

3、创建对象的步骤(静态代码段-静态成员变量-父类构造函数-子类构造函数)使用 I/O buffer 及 NIO


延迟写与提前读策略

异步无阻塞 IO 通信


优先使用组合代替继承

减少对象耦合

避免太深的继承层次带来的对象创建性能损失


合理使用单例模式

无状态对象


线程安全计算机的任何问题都可以通过虚拟层(或者中间层)解决:面向接口编程,7 层网络协议,JVM,编程框架,一致性 hash 算法的虚拟化实现


需要制作一个思维导图进行实践


用户头像

_

关注

还未添加个人签名 2018.09.17 加入

还未添加个人简介

评论

发布
暂无评论
架构师训练营第九周总结