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自动装配如何实现 ...
随机推荐
- 【C】Re06 数组与指针
一.指针和数组 void pointerAndArray() { int array[5] = {1, 2, 3, 4, 5}; printf("pointer array -> %p ...
- 【Layui】15 日期时间选择器 Laydate
文档地址: https://www.layui.com/demo/laydate.html [基本案例] 基本日期与国际日期 <fieldset class="layui-elem-f ...
- MyBatis-Plus文件上传方法
网站的文件上传方法 本地存储上传 // 本地存储方式 MultipartFile接受文件 @PostMapping("/save") public Result save(Stri ...
- 2024-08-03:用go语言,给定一个从 0 开始的字符串数组 `words`, 我们定义一个名为 `isPrefixAndSuffix` 的布尔函数,该函数接受两个字符串参数 `str1` 和
2024-08-03:用go语言,给定一个从 0 开始的字符串数组 words, 我们定义一个名为 isPrefixAndSuffix 的布尔函数,该函数接受两个字符串参数 str1 和 str2. ...
- 为啥华为Atlas的AI卡在二手市场上特别多
首先阐述一下事实,那就是华为Atlas的AI卡在二手市场上特别多,基本上在某鱼上一搜索就是满屏,尤其是关键词:华为Atlas300,但是作为同等level的NVIDIA公司的A100却较之相比少的多, ...
- Ubuntu18.04终端alacritty安装及配置
想在Ubuntu上安装alacritty终端,发现不能直接安装,在网上找到教程: Linux上安装使用最快的 GPU 加速的终端仿真器Alacritty 根据教程成功在Ubuntu18.04桌面系统上 ...
- baselines算法库baselines/common/input.py模块分析
baselines算法库baselines/common/input.py模块代码: import numpy as np import tensorflow as tf from gym.space ...
- 如何在AWS上构建Apache DolphinScheduler
引言 随着云计算技术的发展,Amazon Web Services (AWS) 作为一个开放的平台,一直在帮助开发者更好的在云上构建和使用开源软件,同时也与开源社区紧密合作,推动开源项目的发展. 本文 ...
- 零基础学习人工智能—Python—Pytorch学习(二)
前言 数学的学习跟数学的计算是要分开的,现在回头再去看大学的高数和线性代数,如果只是学习的话,其实一门课程3天,也就学完了. 学校的课程之所以上那么久,其实是为了考试,也就是为计算准备的.计算有意义的 ...
- 使用 extract_sqlaudit_proc 存过分析ob性能问题
最近在某个金融单位核心系统项目做ob的性能压测,期间遇到不少问题,现场两周了每天都加班到凌晨一两点左右,真的是累死. 我其实进ob之前有心理预期,卷就卷吧,八九点下班也能接受,没想到真到了干项目的情况 ...