2. 垃圾收集器参数
参数
描述
-XX:+UseSerialGC
Jvm运行在Client模式下的默认值,打开此开关后,使用Serial + Serial Old的收集器组合进行内存回收
-XX:+UseParNewGC
打开此开关后,使用ParNew + Serial Old的收集器进行垃圾回收
-XX:+UseConcMarkSweepGC
使用ParNew + CMS + Serial Old的收集器组合进行内存回收,Serial Old作为CMS出现“Concurrent Mode Failure”失败后的后备收集器使用。
-XX:+UseParallelGC
Jvm运行在Server模式下的默认值,打开此开关后,使用Parallel Scavenge + Serial Old的收集器组合进行回收
-XX:+UseParallelOldGC
使用Parallel Scavenge + Parallel Old的收集器组合进行回收
-XX:SurvivorRatio
新生代中Eden区域与Survivor区域的容量比值,默认为8,代表Eden:Subrvivor ...
2. 文件IO消耗分析
Linux 在操作文件时,将数据放入文件缓存区,直到内存不够或系统要释放内存给用户进程使用,因此在查看 Linux 内存状况时经常会发现可用的物理内存不多,但 cached 用了很多,这是Linux提升文件IO速度的一种做法。
这种情况下,如物理空闲内存够用,通常在Linux上只有写文件和第一次读取文件时会产生真正的文件IO
在 Linux 中,主要通过 pidstat 来查找文件 IO 的消耗
pidstatpidstat –d –t –p[pid] 1 100 查看线程的 IO 消耗状况,要在 2.6.20 以上版本有效。
参数
含义
TID
表示线程 ID
KB_rd/s
表示每秒读取的 KB 数
KB_wr/s
表示每秒写入的 KB 数
iostat在没有 pidstat 的情况下,只能通过 IOSTAT 来查看整个系统的文件 IO 消耗状况,无法跟踪进程的文件 IO 消耗状况。
直接输入 iostat,可查看各个设备的IO历史情况
参数
含义
tps
是每秒的 IO 请求数
Blk_read/s
是 ...
2. 植⼊插件逻辑
以 Executor 为例,分析MyBatis是如何为Executor实例植入插件逻辑的。Executor实例是在开启 SqlSession 时被创建的
123456789101112131415161718// -☆- DefaultSqlSessionFactorypublic SqlSession openSession() { return openSessionFromDataSource( configuration.getDefaultExecutorType(), null, false);}private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) { Transaction tx = null; try { // 省略部分逻辑 // 创建 Executor fin ...
2. PerpetualCache
PerpetualCache 是一个具有基本功能的缓存类,内部使用了 HashMap 实现缓存功能。它的源码如下:
1234567891011121314151617181920212223242526272829303132333435363738394041public class PerpetualCache implements Cache { private final String id; private Map<Object, Object> cache = new HashMap<Object, Object>(); public PerpetualCache(String id) { this.id = id; } @Override public String getId() { return id; } @Override public int getSize() { ...
2. UnpooledDataSource
UnpooledDataSource从名称上即可知道,该种数据源不具有池化特性。该种数据源每次会返回一个新的数据库连接,而非复用旧的连接。由于UnpooledDataSource无需提供连接池功能,因此它的实现非常简单。核心的方法有三个,分别如下:
initializeDriver - 初始化数据库驱动
doGetConnection - 获取数据连接
configureConnection - 配置数据库连接
初始化数据库驱动使用 JDBC 访问数据库时的情景,在执行SQL之前,通常都是先获取数据库连接。一般步骤都是加载数据库驱动,然后通过 DriverManager 获取数据库连接。UnpooledDataSource 也是使用 JDBC 访问数据库的,因此它获取数据库连接的过程也大致如此,只不过会稍有不同。
1234567891011121314151617181920212223242526// -☆- UnpooledDataSourceprivate synchronized void initializeDriver() throws SQLException ...
2. selectOne ⽅法分析
查询语句对应的方法比较多,有如下几种:
executeWithResultHandler
executeForMany
executeForMap
executeForCursor
这些方法在内部调用了 SqlSession 中的一些 select*方法,比如 selectList、selectMap、selectCursor 等。这些方法的返回值类型是不同的,因此对于每种返回类型,需要有专门的处理方法。
以selectList 方法为例,该方法的返回值类型为 List。但如果我们的 Mapper 或 Dao的接口方法返回值类型为数组,或者 Set,直接将 List 类型的结果返回给 Mapper/Dao 就不合适了。
execute_等方法只是对 select _等方法做了一层简单的封装,因此接下来我们应们应该把目光放在这些 select * 方法上。
selectOne ⽅法分析selectOne 在内部会调用selectList方法,selectOne和selectList方法是有联系的,同时分析selectOne 方法等同于分析selectList 方法。
...
2. 解析映射⽂件
映射文件 包 含 多 种 二 级 节 点 , 比如 , , , 以 及<select|insert|update|delete>等。除此之外,还包含了一些三级节点,比如,,等。
实例123456789101112131415161718192021222324<mapper namespace="xyz.coolblog.dao.AuthorDao"> <cache/> <resultMap id="authorResult" type="Author"> <id property="id" column="id"/> <result property="name" column="name"/> <!-- ... --> </resultMap> <sql ...
2. 解析properties节点
节点的解析工作由 propertiesElement 这个方法完成的
1234<properties resource="jdbc.properties"> <property name="jdbc.username" value="coolblog"/> <property name="hello" value="world"/></properties>
我们参照上面的配置,来分析 propertiesElement 方法的逻辑。如下
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263// -☆- XMLConfigBuilderprivate void propertiesElement(XNode context) throws Ex ...
2. 重排序
重排序是指编译器和处理器为了优化程序性能而对指令序列进行重新排序的一种手段
数据依赖性如果两个操作访问同一个变量,且这两个操作中有一个为写操作,此时这两个操作之间就存在数据依赖性。数据依赖分为下列3种类
名称
代码示例
说明
写后读
a=1; b=a;
写一个变量后,再读这个位置
写后写
a=1; a=2;
写一个变量后,再写这个变量
读后写
a=b; b=1;
读一个变量后,再写这个变量
上面3种情况,只要重排序两个操作的执行顺序,程序的执行结果就会被改变。
前面提到过,编译器和处理器可能会对操作做重排序。编译器和处理器在重排序时,会遵守数据依赖性,编译器和处理器不会改变存在数据依赖关系的两个操作的执行顺序。
这里所说的数据依赖性仅针对单个处理器中执行的指令序列和单个线程中执行的操作,不同处理器之间和不同线程之间的数据依赖性不被编译器和处理器考虑。
as-if-serial语义as-if-serial语义的意思是:不管怎么重排序(编译器和处理器为了提高并行度),(单线程)程序的执行结果不能被改 ...
2. 并发机制底层实现原理
JAVA代码编译后会变成JAVA字节码,字节码被类加载器加载到JVM中,JVM执行字节码,最终需要转换为汇编指令在CPU上执行。
JAVA中使用的并发机制,依赖于JVM的实现和CPU的指令
volatile的应用它比synchronized使用执行成本更低,因为它不会引起线程上下文切换和调度。
volatile定义和原理
属于
英文单词
描述
内存屏障
memory barriers
一组处理器指令,实现对内存操作的顺序限制
缓冲行
cache line
缓存中可以分配的最小存储单��
原子操作
atomic operations
不可中断的一个或一系列操作
缓冲行填充
cache line fill
当处理器识别从内存中读取操作数是可缓存的,处理器读取整合缓冲行到合适的内存(L1,L2,L3或所有)
缓存命中
cache hit
如果进行高速缓存行操作的内存位置仍然是下次处理器访问的地址时,处理器从缓存读取数据,而不是从内存
写命中
write hit
当处理器将操作数写回到一个内存缓存的区域时,会检查这个缓存的内存地址是否在缓存行中,如果存在一 ...