diff --git a/jvm/JVM简介.md b/jvm/JVM简介.md new file mode 100644 index 0000000..adf0aed --- /dev/null +++ b/jvm/JVM简介.md @@ -0,0 +1,43 @@ +# JVM简介 + +write once run everywhere + +## jvm空间加载运行 + +### 空间、运行时数据区 + +- 线程共享 + - Heap堆:在虚拟机启动时创建,此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。存储数据不是线程安全的,**堆和常量池**空间不足时会触发OutOfMemoryError + - MetaSpace元数据区:在1.8之后取代Method Area 方法区永久代,不在jvm中,使用本地内存,受操作系统内存限制。存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。 +- 线程隔离 + - VM Stack虚拟机栈:每个线程创建一个单独的运行时堆栈。对于每一个方法调用,一个称为栈内存栈帧被创建。所有局部变量将被创建在栈内存中。栈区域时线程安全的,因为他不是一个共享资源。 + - Navive Method Stack本地方法栈:与虚拟机所发挥的作用是非常相似的,其区别不过是虚拟机栈为虚拟机执行java方法(也就是字节码)服务,而本地方法栈则是为虚拟机使用到的Native方法服务。 + - Program Counter Register 程序计数器:每个线程必须分开程序计数器登记,当前执行的指令一旦被执行,程序计数器更新下一个指令。一块较小的内存空间。他的作用可以看做是当前线程所执行的字节码的行号指示器。 + +### 加载 + +- 类加载器 + - Bootstrap:加载环境变量中$JAVA_HOME/jre/lib/rt.jar里所有的class,不是ClassLoader子类。 + - Extension:加载java平台中扩展功能的一些jar包。包括环境变量中$JAVA_HOME/jre/lib/*.jar或-Djava.ext.dirs指定目录下的jar包。 + - Application:加载classpath中指定的jar包及目录中class。 + - Custom自定义:应用程序根据自身需要自定义的ClassLoader,如tomcat、jboss都会根据j2ee规范自行是实现ClassLoader + +### 链接 + +- 验证:字节码校验器会检查生成的字节码是否正确,如果验证失败会停止运行 +- 准备:对于所有静态变量内存分配和默认值分配 +- 识别:解析或识别是从运行时常量池的符号引用中动态具体的过程。 + +### 初始化 + +- 类或接口的初始化由执行类或接口初始化方法构成,这里所有的静态变量与原来的值将被指派,静态块将被执行。 + +## 内存空间分配 + +![image-20211020152033799](img\image-20211020152033799.png) + +## 垃圾收集器 + +- 并行parallel:多个垃圾收集线程并行工作,此时用户线程处于等待状态。 +- 并发concurrent:用户线程和垃圾收集线程同时执行。 +- 吞吐量:用户代码执行时间/(用户代码执行时间+垃圾收集时间) diff --git a/jvm/img/image-20211020152033799.png b/jvm/img/image-20211020152033799.png new file mode 100644 index 0000000..d507df4 Binary files /dev/null and b/jvm/img/image-20211020152033799.png differ diff --git a/spring/spring源码解读/spring01启动.md b/spring/spring源码解读/spring01启动.md new file mode 100644 index 0000000..f82b077 --- /dev/null +++ b/spring/spring源码解读/spring01启动.md @@ -0,0 +1,23 @@ +# 第一章启动 + +## 说明 + +1. 使用spring版本5.3.5 +2. 起始类ClassPathXmlApplicationContext,可以使用org.springframework.context.support.GenericApplicationContext自定义读取配置 + +```java +GenericApplicationContext ctx = new GenericApplicationContext(); +XmlBeanDefinitionReader xmlReader = new XmlBeanDefinitionReader(ctx); +xmlReader.loadBeanDefinitions(new ClassPathResource("applicationContext.xml")); +PropertiesBeanDefinitionReader propReader = new PropertiesBeanDefinitionReader(ctx); +propReader.loadBeanDefinitions(new ClassPathResource("otherBeans.properties")); +ctx.refresh(); +MyBean myBean = (MyBean) ctx.getBean("myBean"); +``` + +## 解读ClassPathXmlApplicationContext + +1. 从构造函数中,点击追踪父类默认加载:org.springframework.context.support.AbstractApplicationContext +2. 加载构造函数中传入的参数(String... locations),循环处理路径locations +3. 是否刷新加载到的内容 + diff --git a/spring/spring源码解读/spring02刷新.md b/spring/spring源码解读/spring02刷新.md new file mode 100644 index 0000000..33d517f --- /dev/null +++ b/spring/spring源码解读/spring02刷新.md @@ -0,0 +1,88 @@ +# 第二章刷新 + +synchronized使用当前类中final对象。 + +## 获取启动指标StartupStep + +```java +StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh"); +``` + +## 刷新前预处理prepareRefresh() + +1. 记录启动时间 +2. 设置当前状态未关闭 +3. 设置当前状态活跃 +4. 初始化上下文资源中的占位符,initPropertySources(); +5. 校验上下文可解析,getEnvironment().validateRequiredProperties(); +6. 初始化监听器earlyApplicationListeners(LinkedHashSet) +7. 初始化事件earlyApplicationEvents(LinkedHashSet) + +## 刷新内部类obtainFreshBeanFactory() + +1. 刷新工厂refreshBeanFactory() + 1. 销毁类 + 2. 关闭工厂 + 3. 创建新的工厂 + 4. 设置工厂customizeBeanFactory序列化类名加对象十六进制,弱引用。 + 5. 定制工厂设置是否可重写,是否可循环引用 + 6. 加载工厂loadBeanDefinitions,XmlBeanDefinitionReader +2. 返回工厂getBeanFactory() + +## 装配工厂prepareBeanFactory + +1. 设置加载类 +2. 是否支持spel +3. 设置Property编辑器 +4. 设置类后置处理器(post processor)BeanPostProcessor,添加感知处理器AwareProcessor +5. 忽略加载的其他感知接口 +6. 注册解析接口:BeanFactory、ResourceLoader、ApplicationEventPublisher、ApplicationContext +7. 添加后置处理器ApplicationListenerDetector内部类检测 +8. 图片设置 +9. 加载环境中的配置信息 + +## 内部类处理配置postProcessBeanFactory(beanFactory); + +## 设置启动步骤spring.context.beans.post-process + +## 将工厂注册为bean,invokeBeanFactoryPostProcessors(beanFactory) + +## 注册工厂bean,registerBeanPostProcessors(beanFactory) + +## 启动步骤spring.context.beans.post-process完成 + +## 初始化message source,initMessageSource() + +## 初始化事件多播器initApplicationEventMulticaster() + +## onRefresh() + +## 注册监听器registerListeners() + +## 初始化剩余信息finishBeanFactoryInitialization(beanFactory) + +## 完成刷新 + +1. 清空资源缓存 +2. 初始化生命周期处理器 +3. 启动生命周期 +4. 发布事件 +5. NativeDetector + +## 异常处理 + +1. 销毁之前创建的单例 +2. 设置活跃状态为false +3. 抛出异常 + +## finally + +1. 清空缓存 +2. 结束spring.context.refresh + + + + + + + diff --git a/spring/spring源码解读/spring03BeanFactory.md b/spring/spring源码解读/spring03BeanFactory.md new file mode 100644 index 0000000..84e8455 --- /dev/null +++ b/spring/spring源码解读/spring03BeanFactory.md @@ -0,0 +1,38 @@ +## 顺序获取单例 + +1. private final Map singletonObjects = new ConcurrentHashMap<>(256); +2. private final Map earlySingletonObjects = new ConcurrentHashMap<>(16); +3. private final Map> singletonFactories = new HashMap<>(16); + +## 循环依赖 + +```java +// 单例顺序获取失败 +// Fail if we're already creating this bean instance: +// We're assumably within a circular reference. +``` + +1. 判断是否存在父类中,如果存在从父类中获取。 +2. 设置正在创建 +3. RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); +4. 判断单例、原型或者其他 +5. 创建bean,检验检测状态 + 1. Make sure bean class is actually resolved at this point, and clone the bean definition in case of a dynamically resolved Class which cannot be stored in the shared merged bean definition. + 2. doCreateBean + 1. createBeanInstance + 2. Eagerly cache singletons to be able to resolve circular references even when triggered by lifecycle interfaces like BeanFactoryAware.放入三级缓存中addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)) + 3. Give any InstantiationAwareBeanPostProcessors the opportunity to modify the state of the bean before properties are set. This can be used, for example,to support styles of field injection. + + + + + +## 重要类 + +```java + +BeanDefinition、ClassLoader +``` + + + diff --git a/spring/spring源码解读/加载.md b/spring/spring源码解读/加载.md new file mode 100644 index 0000000..9f2f455 --- /dev/null +++ b/spring/spring源码解读/加载.md @@ -0,0 +1,15 @@ +设置是否加载 + +```java + @Bean + @ConditionalOnProperty( + value = {"feign.compression.response.enabled"}, + havingValue = "true" + ) + public CloseableHttpClient customHttpClient(HttpClientConnectionManager httpClientConnectionManager, FeignHttpClientProperties httpClientProperties) { + HttpClientBuilder builder = HttpClientBuilder.create().disableCookieManagement().useSystemProperties(); + this.httpClient = this.createClient(builder, httpClientConnectionManager, httpClientProperties); + return this.httpClient; + } +``` +