jvm类加载器及类加载程序
加载器
1)BootstrapClassLoader(启动类加载器)
负责加载$JAVA_HOME中jre/lib/rt.jar里所有的class,加载System.getProperty(“sun.boot.class.path”)所指定的门路或jar。
2)ExtensionClassLoader(规范扩大类加载器)
负责加载java平台中扩大性能的一些jar包,包含$JAVA_HOME中jre/lib/*.jar或-Djava.ext.dirs指定目录下的jar包。载System.getProperty(“java.ext.dirs”)所指定的门路或jar。
3)AppClassLoader(零碎类加载器)
负责记录classpath中指定的jar包及目录中class
4)CustomClassLoader(自定义加载器)
属于应用程序依据本身须要自定义的ClassLoader,如tomcat、jboss都会依据j2ee标准自行实现
类加载器的程序
1)加载过程中会先查看类是否被已加载,查看程序是自底向上,从Custom ClassLoader到BootStrap ClassLoader逐层查看,只有某个classloader已加载就视为已加载此类,保障此类只所有ClassLoader加载一次。而加载的程序是自顶向下,也就是由下层来逐层尝试加载此类。
2)在加载类时,每个类加载器会将加载工作上交给其父,如果其父找不到,再由本人去加载。
3)Bootstrap Loader(启动类加载器)是最顶级的类加载器了,其父加载器为null。
spi
spi能带来的益处:
不须要改变源码就能够实现扩大,解耦。
实现扩大对原来的代码简直没有侵入性。
只须要增加配置就能够实现扩大,合乎开闭准则。
要害信息:ServiceLoader能够获取扩大实现的类实例
写好接口及实现类;
在resources目录下新建META-INF/services目录,并且在这个目录下新建一个与上述接口的全限定名统一的文件,在这个文件中写入接口的实现类的全限定名:
https://www.cnblogs.com/jy107...
B+tree
二叉树、均衡二叉树
B树结构
B树特点: 每个节点都存储了子节点的指针和本节点的键值及数据; 准确查找ok,范畴查找有较多的io操作,范畴越大,性能越低;
B+树结构
B+ 树特点1.非叶子节点只存储键值信息。2.所有叶子节点之间都有一个双向链指针。(晋升插入操作效率)3.数据记录都寄存在叶子节点中。
sql优化
slow_query配置 查看慢sql日志
最左匹配
explain 执行打算
binlog主从同步提早
硬件问题晋升硬件
分库分表
- 针对数据库方面的拆分次要是联合分库分表来实现,即对于分库,则依据业务内聚性,拆分为几个绝对独立的子服务,各个子服务应用独立的数据库离开部署,则能够将写操作扩散到各个数据库,各个数据库的复制流量绝对较小,从而通过分而治之的办法来升高整体的提早
线程池**
Java线程池参数
corePoolSize 线程池外围线程大小
maximumPoolSize 线程池最大线程数量
keepAliveTime 闲暇线程存活工夫
Timeunit 闲暇线程存活工夫单位
workQueue 工作队列
①ArrayBlockingQueue②LinkedBlockingQuene③SynchronousQuene④PriorityBlockingQueue
threadFactory 线程工厂
handler 回绝策略
jvm调参加内存问题排查
volatile
1.保障有序性
2.保障可见性
3.不保障原子性
场景:
1)对变量的写操作不依赖于以后值
2)该变量没有蕴含在具备其余变量的不变式中
保障对变量操作的原子性才可应用volatile
gc
回收哪些内存
可达性剖析算法:每个对象都被对象的援用,root object
两种回收算法
标记删除法、标记整顿法
内存模型 minor gc为年老代区域回收 majorgc 为老年代区域回收
常见垃圾回收器CMS G1, jdk9后默认从CMS切换到G1
jvm内存模型
线程隔离:程序计数器(Program Counter Register)、虚拟机栈(VM Stack)、本地办法栈(Native Method Stack)
线程共享:堆(Heap)、办法区(Method Area)
堆内存是 JVM 内存中最大的一块内存空间,该内存被所有线程共享,简直所有对象和数组都被调配到了堆内存中。
办法区次要是用来寄存已被虚拟机加载的类相干信息,包含类信息、常量池(字符串常量池以及所有根本类型都有其相应的常量池)、运行时常量池
程序计数器记录各个线程执行的字节码的地址,例如,分支、循环、跳转、异样、线程复原等都依赖于计数器
虚拟机栈是线程公有的内存空间,它和 Java 线程一起创立。
当创立一个线程时,会在虚拟机栈中申请一个线程栈,用来保留办法的局部变量、操作数栈、动静链接办法和返回地址等信息,并参加办法的调用和返回。
本地办法栈跟虚拟机栈的性能相似,虚拟机栈用于治理 Java 办法的调用,而本地办法栈则用于治理本地办法的调用。
但本地办法并不是用 Java 实现的,而是由 C 语言实现的。
每一个办法的调用都随同着栈帧的入栈操作,办法的返回则是栈帧的出栈操作
单例
public class Singleton { private volatile static Singleton instance = null; private Singleton() {} public static Singleton getInstance() { if (instance == null) { synchronized (Singleton.class) {// 1 if (instance == null) {// 2 instance = new Singleton();// 3 } } } return instance; } }
这里是次要是要了解为什么要应用volatile润饰变量才行,是因为:
volatile变量规定:对一个变量的写操作后行产生于前面对这个变量的读操作,所以才不会呈现对象还在创立就被其余线程拿去应用的状况,其余线程都会失去一个创立好的对象
应用外部类实现提早加载
public class Singleton { private Singleton() {} private static class Holder { private static Singleton instance = new Singleton(); } public static Singleton getInstance() { // 外围类能间接拜访外部类(不论是否是动态的)的公有变量 return Holder.instance; } }