springboot 启动慢分析
JVM参数设置
1. 生成GC日志并网站在线分析
- 生成gc日志命令
-Xloggc:./gc.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps
- 在线分析网站
https://gceasy.io/ - 调整过程:
根据GC日志分析得到年轻代GC频繁,没有老年代GC;
调整年轻代大小为堆的1/2,性能并没有优化,反而有了更多消耗时间更长的GC
结论:
工程启动慢与年轻代GC频繁无关
2. 生成dump文件分析
- 生产dump文件命令
jmap -dump:format=b,file=./heap.hprof 进程号
结果:没有发现有个别大对象占用大量内存的情况
3.分析日志
[2021-09-03 10:42:58.668] - [INFO] - [main] - [org.springframework.aop.framework.CglibAopProxy] - Unable to proxy interface-implementing method [public final java.util.List com.epoch.bdp.util.service.excel.AbstractExcelProcess.getExcelHeader(com.epoch.bdp.util.service.excel.context.ExcelProcessContext)] because it is marked as final: Consider using interface-based JDK proxies instead!
结论:部分被代理类因为类中有final修饰的方法,无法被cglib进行代理
4.JVM启动参数优化
这里主要涉及的启动参数设置是下面两个:
- -XX:TieredStopAtLevel=1
使用C1编译器,又称为客户端模式,相对于C2也就是服务端模式,C1编译生成的机器码更加关注快速启动但是由于机器码没有经过编译优化所以不适合在线上环境稳定运行。 - -Xverify:none/ -noverify
通过去除字节码的验证来提升JVM启动速度,同样不适合线上对安全有要求的环境使用。
结论:这两种方式 都不适用于生产环境,所以并未启用
5.springboot 懒加载方案
springboot2.2以后支持配置全局懒加载机制,springboot2.2以前实现BeanFactoryPostProcessor 类。
但是存在以下问题:
- 大部分对象启动时未初始化,不好估算应用使用内存
- 启动时不加载部分类,如果有错误不会抛出,不容易发现问题
- 第一次请求是时间会很慢,后续请求不会有此问题
结论:考虑到上面的影响,以及测试过程中发现很多对象配置为懒加载会影响项目启动,所以未采用
6.判断类的加载时间
package com.epoch.boot.config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
/**
* 〈一句话功能简述〉
*
* @author 刘建宇
* @since ECS2.0
*/
@Component
public class BeanInitCostTimeBeanPostProcessor implements BeanPostProcessor {
private static final Logger logger = LoggerFactory.getLogger(BeanInitCostTimeBeanPostProcessor.class);
private static final ConcurrentHashMap<String, Long> START_TIME = new ConcurrentHashMap<>();
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
START_TIME.put(beanName, System.currentTimeMillis());
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if(Objects.nonNull(START_TIME.get(beanName))){
long costTime = System.currentTimeMillis() - START_TIME.get(beanName);
if(costTime>300) {
logger.error("beanName:{},cost:{}",beanName,costTime);
}
}
START_TIME.clear();
return bean;
}
}
结论:发现有个别对象初始化时占用时间较长
7. 分析aop
注解说明
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({AspectJAutoProxyRegistrar.class})
public @interface EnableAspectJAutoProxy {
// true:使用cglib代理,false:使用jdk代理
boolean proxyTargetClass() default false;
// 控制代理的暴露方式,解决内部调用不能使用代理的场景,默认为false.
boolean exposeProxy() default false;
}
最后判断结果为:因为项目中配置了大量AOP切面类,严重影响了启动速度
springboot 启动慢分析的更多相关文章
- SpringBoot启动原理分析
用了差不多两年的SpringBoot了,可以说对SpringBoot已经很熟了,但是仔细一想SpringBoot的启动流程,还是让自己有点懵逼,不得不说是自己工作和学习的失误,所以以此文对Spring ...
- SpringBoot启动流程分析(五):SpringBoot自动装配原理实现
SpringBoot系列文章简介 SpringBoot源码阅读辅助篇: Spring IoC容器与应用上下文的设计与实现 SpringBoot启动流程源码分析: SpringBoot启动流程分析(一) ...
- SpringBoot启动流程分析(六):IoC容器依赖注入
SpringBoot系列文章简介 SpringBoot源码阅读辅助篇: Spring IoC容器与应用上下文的设计与实现 SpringBoot启动流程源码分析: SpringBoot启动流程分析(一) ...
- SpringBoot启动流程分析(一):SpringApplication类初始化过程
SpringBoot系列文章简介 SpringBoot源码阅读辅助篇: Spring IoC容器与应用上下文的设计与实现 SpringBoot启动流程源码分析: SpringBoot启动流程分析(一) ...
- SpringBoot启动流程分析(二):SpringApplication的run方法
SpringBoot系列文章简介 SpringBoot源码阅读辅助篇: Spring IoC容器与应用上下文的设计与实现 SpringBoot启动流程源码分析: SpringBoot启动流程分析(一) ...
- SpringBoot启动流程分析(三):SpringApplication的run方法之prepareContext()方法
SpringBoot系列文章简介 SpringBoot源码阅读辅助篇: Spring IoC容器与应用上下文的设计与实现 SpringBoot启动流程源码分析: SpringBoot启动流程分析(一) ...
- SpringBoot启动流程分析(四):IoC容器的初始化过程
SpringBoot系列文章简介 SpringBoot源码阅读辅助篇: Spring IoC容器与应用上下文的设计与实现 SpringBoot启动流程源码分析: SpringBoot启动流程分析(一) ...
- SpringBoot启动流程分析原理(一)
我们都知道SpringBoot自问世以来,一直有一个响亮的口号"约定优于配置",其实一种按约定编程的软件设计范式,目的在于减少软件开发人员在工作中的各种繁琐的配置,我们都知道传统的 ...
- SpringBoot启动流程分析
前景提示 @ComponentScan 的处理都放在org.springframework.context.annotation.ConfigurationClassParser#doProcess ...
- SpringBoot源码学习3——SpringBoot启动流程
系列文章目录和关于我 一丶前言 在 <SpringBoot源码学习1--SpringBoot自动装配源码解析+Spring如何处理配置类的>中我们学习了SpringBoot自动装配如何实现 ...
随机推荐
- “refer to”和“refer to as”在英语中的用法有所不同
"refer to"和"refer to as"在英语中的用法有所不同,具体区别如下: Refer to "Refer to"意为" ...
- 实用英语:英文中经常出现“ i.e.、e.g.、etc."缩写究竟啥意思?
地址: https://mp.weixin.qq.com/s?__biz=MzIyMzU5NDE1Mw==&mid=2247487840&idx=1&sn=013992683c ...
- 域名所有权验证 —— DNS TXT 域名验证
参考: https://help.aliyun.com/zh/cdn/getting-started/verify-the-ownership-of-a-domain-name https://blo ...
- ubuntu18.04 安装wine64出现错误: X 64-bit development files not found.
ubuntu18.04 编译源码方式安装 wine6.11 , 报错: 缺少依赖,解决方法如下: sudo apt install xserver-xorg-dev 参考: https://bl ...
- 强化学习算法如何将GPU利用率提高到100%——在线强化学习如何将GPU利用率提升至100%
一直有个疑问,那就是"强化学习算法如何将GPU利用率提高到100%",在一些论坛中也有人会提出这样的问题,但是一直也没有人比较正面的回答过这个问题,为此正好自己又想到了这么一个问题 ...
- python3.9的nogil版本编译pytorch2.0.1源码报错——失败
关于python3.9的nogil版本参看: PEP 703作者给出的一种no-GIL的实现--python3.9的nogil版本 ================================== ...
- vscode下如何把缩进为2个空格的python项目改为4个空格的缩进
最近在看老项目的代码,是python2.7年代的项目,那个时候很多的python项目都是使用2个空格,不过现在估计大多数人写python项目都是使用4个空格的了,而我看这两个空格的项目代码也是感觉十分 ...
- 架构演化学习思考(4) --- IOC的学习认识
架构演化学习思考(4) IOC的学习认识[1] IOC相关概念认识 什么是IOC? IOC全称为 Inversion Of Control ,即控制反转.它是一种控制思想,可以解释为类和类之间的依赖关 ...
- Java 大文件IO操作效率对比【我说说 你瞅瞅】
Java 文件IO操作效率对比 注:本文只做时间消耗层面对比,内存占用层面需要特别关注! 1. 参数说明 文件总大小:2,111,993,850 字节(2.11 GB) static String d ...
- 瑞芯微rk356x板子快速上手
@ 目录 rk3568 CPU GPU NPU VPU 一.编译环境要求 二.编译前准备 0)开发板型号 1)安装第三方编译工具 2)设置adb路径 3)安装USB驱动DriverAssitant_v ...