jvm-spring

This commit is contained in:
huayu 2021-10-20 16:34:53 +08:00
parent f47c556d9b
commit db00dd970e
6 changed files with 207 additions and 0 deletions

43
jvm/JVM简介.md Normal file
View File

@ -0,0 +1,43 @@
# JVM简介
write once run everywhere
## jvm空间加载运行
### 空间、运行时数据区
- 线程共享
- Heap堆在虚拟机启动时创建此内存区域的唯一目的就是存放对象实例几乎所有的对象实例都在这里分配内存。存储数据不是线程安全的<u>**堆和常量池**</u>空间不足时会触发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用户线程和垃圾收集线程同时执行。
- 吞吐量:用户代码执行时间/(用户代码执行时间+垃圾收集时间)

Binary file not shown.

After

Width:  |  Height:  |  Size: 175 KiB

View File

@ -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. 是否刷新加载到的内容

View File

@ -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. 初始化监听器earlyApplicationListenersLinkedHashSet
7. 初始化事件earlyApplicationEventsLinkedHashSet
## 刷新内部类obtainFreshBeanFactory()
1. 刷新工厂refreshBeanFactory()
1. 销毁类
2. 关闭工厂
3. 创建新的工厂
4. 设置工厂customizeBeanFactory序列化类名加对象十六进制弱引用。
5. 定制工厂设置是否可重写,是否可循环引用
6. 加载工厂loadBeanDefinitionsXmlBeanDefinitionReader
2. 返回工厂getBeanFactory()
## 装配工厂prepareBeanFactory
1. 设置加载类
2. 是否支持spel
3. 设置Property编辑器
4. 设置类后置处理器post processorBeanPostProcessor添加感知处理器AwareProcessor
5. 忽略加载的其他感知接口
6. 注册解析接口BeanFactory、ResourceLoader、ApplicationEventPublisher、ApplicationContext
7. 添加后置处理器ApplicationListenerDetector内部类检测
8. 图片设置
9. 加载环境中的配置信息
## 内部类处理配置postProcessBeanFactory(beanFactory);
## 设置启动步骤spring.context.beans.post-process
## 将工厂注册为beaninvokeBeanFactoryPostProcessors(beanFactory)
## 注册工厂beanregisterBeanPostProcessors(beanFactory)
## 启动步骤spring.context.beans.post-process完成
## 初始化message sourceinitMessageSource()
## 初始化事件多播器initApplicationEventMulticaster()
## onRefresh()
## 注册监听器registerListeners()
## 初始化剩余信息finishBeanFactoryInitialization(beanFactory)
## 完成刷新
1. 清空资源缓存
2. 初始化生命周期处理器
3. 启动生命周期
4. 发布事件
5. NativeDetector
## 异常处理
1. 销毁之前创建的单例
2. 设置活跃状态为false
3. 抛出异常
## finally
1. 清空缓存
2. 结束spring.context.refresh

View File

@ -0,0 +1,38 @@
## 顺序获取单例
1. private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
2. private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);
3. private final Map<String, ObjectFactory<?>> 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
```

View File

@ -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;
}
```