猿码天地-Java架构师-帮你进大厂系列
2021-03-21 14:54:09 1 举报
AI智能生成
Java架构师学习路线-》对标一线大厂P7-》帮你进大厂系列
作者其他创作
大纲/内容
猿码天地-Java架构师-帮你进大厂系列
性能调优专题
JVM性能调优
类加载机制深度解析
类加载过程
加载
在硬盘上查找并通过IO读入字节码文件,使用到类时才会加载,例如调用类的main()方法,new对象等等,在加载阶段会在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口。
验证
校验字节码文件的正确性
准备
给类的静态变量分配内存,并赋予默认值
解析
初始化
对类的静态变量初始化为指定的值,执行静态代码块。
Launcher类
ExtClassLoader扩展类加载器
AppClassLoader应用类加载器
类加载器和双亲委派机制
类加载器分类
引导类加载器
负责加载支撑JVM运行的位于JRE的lib目录下的核心类库,比如rt.jar、charsets.jar等
扩展类加载器
负责加载支撑JVM运行的位于JRE的lib目录下的ext扩展目录中的JAR类包
应用类加载器
负责加载ClassPath路径下的类包,主要就是加载你自己写的那些类
自定义加载器
负责加载用户自定义路径下的类包
双亲委派机制
为什么要使用双亲委派机制?
沙箱安全机制:自己写的java.lang.String.class类不会被加载,这样便可以防止核心API库被随意篡改
避免类的重复加载:当父亲已经加载了该类时,就没有必要子ClassLoader再加载一次,保证被加载类的唯一性
自定义类加载器
打破双亲委派机制
重写类加载方法,实现自己的加载逻辑,不委派给双亲加载
JVM整体结构深入解析
JDK体系结构
Java语言的跨平台特性
JVM整体结构及内存模型
FILO:程序执行时,每个方法都会在栈分配内存空间,栈具有先进后出FILO特点。比如一个main方法,栈内存先分配一块空间,然后调用另外一个方法A,也会给A分配一块栈内存,A执行完成后就会出栈,释放栈内存,然后执行主方法main,这就是FILO。Javap -c 字节码文件(查看字节码文件)new的对象一般放堆内存,堆里面存放对象的内存地址栈(线程)、本地方法栈、程序计数器是每个线程独有的;堆和方法区是线程共有的。静态变量、缓存等会流转到老年代;如果程序死循环,最终到老年代然后发生OOM;老年代满了会触发fullgcheap:java堆(java heap)。它包括老年代和新生代(图中Eden/S0/S1 三个统称新生代,分为Eden区和两个Survivor区域),他们默认是8:1分配内存。
JVM包含三部分
类装载(Class Loader)子系统
字节码执行引擎(Execution Engine)
运行时数据区(Runtime Data Area)
线程共享数据区
堆(Heap)
作用
存放对象实例,几乎所有的对象实例和数组都是在这里分配内存。
方法区
JDK8没有这个概念,取代的是“元空间”
线程私有数据区
栈Stack(也称线程、虚拟机栈(Java Vitual Machine Stack))
栈帧
异常
本地方法栈
程序计数器
执行过程
Java程序从源文件创建到程序运行要经过两大步骤:1、源文件由编译器编译成字节码(ByteCode) 2、字节码由java虚拟机解释运行。因为java程序既要编译同时也要经过JVM的解释运行,所以说Java被称为半解释语言。
JVM内存参数设置
Spring Boot程序的JVM参数设置格式(Tomcat启动直接加在bin目录下catalina.sh文件里):java -Xms2048M -Xmx2048M -Xmn1024M -Xss512K -XX:MetaspaceSize=256M -XX:MaxMetaspaceSize=256M -jar microservice-eureka-server.jar
-Xss:每个线程的栈大小-Xms:初始堆大小,默认物理内存的1/64-Xmx:最大堆大小,默认物理内存的1/4-Xmn:新生代大小-XX:NewSize:设置新生代初始大小-XX:NewRatio:默认2表示新生代占年老代的1/2,占整个堆内存的1/3。-XX:SurvivorRatio:默认8表示一个survivor区占用1/8的Eden内存,即1/10的新生代内存。关于元空间的JVM参数有两个:-XX:MetaspaceSize=N和 -XX:MaxMetaspaceSize=N-XX:MaxMetaspaceSize: 设置元空间最大值, 默认是-1, 即不限制, 或者说只受限于本地内存大小。-XX:MetaspaceSize: 指定元空间触发Fullgc的初始阈值(元空间无固定初始大小), 以字节为单位,默认是21M左右,达到该值就会触发full gc进行类型卸载, 同时收集器会对该值进行调整: 如果释放了大量的空间, 就适当降低该值; 如果释放了很少的空间, 那么在不超过-XX:MaxMetaspaceSize(如果设置了的话) 的情况下, 适当提高该值。这个跟早期jdk版本的-XX:PermSize参数意思不一样,-XX:PermSize代表永久代的初始容量。由于调整元空间的大小需要Full GC,这是非常昂贵的操作,如果应用在启动的时候发生大量Full GC,通常都是由于永久代或元空间发生了大小调整,基于这种情况,一般建议在JVM参数中将MetaspaceSize和MaxMetaspaceSize设置成一样的值,并设置得比初始值要大,对于8G物理内存的机器来说,一般我会将这两个值都设置为256M。
通过VM Args:-xms512m -Xmx512m -XX:+HeapDumpOnOutofMemoryError -Xmn100m -XX:SurvivorRatio=8 设置初始堆内存、最大堆内存、内存异常打印dump、 新生代内存、新生代内存分配比例(8:1:1),因为Heap分为新生代跟老年代,所以512M- 100M=412M,老年代就是412M(初始内存跟最大内存最好相等,防止内存不够时扩充内 存或者Full GC,导致性能降低)
JVM内存参数大小该如何设置?
日均百万级订单交易系统如何设置JVM参数
结论
JVM内存分配机制详解
对象创建
流程图
类加载检查
new对象-》常量池检查类的符号引用-》是否被加载过
分配内存
从堆中分配
划分内存方法
指针碰撞(Bump the Pointer)(默认用指针碰撞)
空闲列表(Free List)
并发问题解决
CAS(compare and swap)
初始化零值
设置对象头
执行<init>方法
对象内存分配
栈上分配
逃逸分析
标量替换
Eden分配
大多数情况下,对象在新生代中 Eden 区分配。当 Eden 区没有足够空间进行分配时,虚拟机将发起一次Minor GC。
Minor GC和Full GC
大对象至直接进入老年代
长期存活的对象将进入老年代
对象动态年龄判断
老年代空间分配担保机制
对象内存回收
引用计数法
可达性分析算法(重要)
GC Roots根节点:线程栈的本地变量、静态变量、本地方法栈的变量等等。
常见引用类型
强引用
软引用
弱引用
虚引用
finalize()方法
作用:判定对象是否存活
即使在可达性分析算法中不可达的对象,也并非是“非死不可”的,这时候它们暂时处于“缓刑”阶段,要真正宣告一个对象死亡,至少要经历再次标记过程。标记的前提是对象在进行可达性分析后发现没有与GC Roots相连接的引用链。
例子
无用类判断
满足三个条件
该类所有的对象实例都已经被回收,也就是 Java 堆中不存在该类的任何实例。
加载该类的 ClassLoader 已经被回收。
该类对应的 java.lang.Class 对象没有在任何地方被引用,无法在任何地方通过反射访问该类的方法。
JVM字节码文件结构深度剖析
垃圾收集算法与垃圾收集器ParNew&CMS详解
垃圾收集算法
分代收集理论
分代收集(Generational Collector)算法的将堆内存划分为新生代、老年代和永久代。新生代又被进一步划分为 Eden 和 Survivor 区,其中 Survivor 由 FromSpace(Survivor0)和 ToSpace(Survivor1)组成。所有通过new创建的对象的内存都在堆中分配,其大小可以通过-Xmx和-Xms来控制。分代收集,是基于这样一个事实:不同的对象的生命周期是不一样的。因此,可以将不同生命周期的对象分代,不同的代采取不同的回收算法进行垃圾回收,以便提高回收效率。
特别地,在分代收集算法中,对象的存储具有以下特点:1、对象优先在 Eden 区分配。2、大对象直接进入老年代。3、长期存活的对象将进入老年代,默认为 15 岁。
标记-复制算法
标记-清除算法
问题
效率问题 (如果需要标记的对象太多,效率不高)空间问题(标记清除后会产生大量不连续的碎片)
标记-整理算法
垃圾收集器
分类图
Serial收集器
串行收集器、单线程
STW
新生代采用标记-复制算法,老年代采用标记-整理算法。
优点
简单而高效(与其他收集器的单线程相比)
Parallel Scavenge收集器
Parallel收集器其实就是Serial收集器的多线程版本
关注点
提高吞吐量、高效利用CPU
JDK8默认使用
Parallel Scavenge收集器和Parallel Old收集器,JDK8默认的新生代和老年代收集器。
ParNew收集器
CMS收集器
缩短回收停顿时间为目标、注重用户体验
真正意义的并发收集器、让垃圾收集线程与用户线程(基本上)同时工作
初始标记
并发标记
重新标记
并发清理
并发重置
优缺点
并发收集、低停顿
缺点
CMS的相关核心参数
亿级流量电商系统如何优化JVM参数设置(ParNew+CMS)
下单流程分析
垃圾收集底层算法实现
三色标记
记忆集与卡表
垃圾收集器G1&ZGC详解
G1收集器
G1将Java堆划分为多个大小相等的独立区域(Region),JVM目标是不超过2048个Region
Region大小:一般Region大小等于堆大小除以2048,比如堆大小为4096M,则Region大小为2M,当然也可以用参数\"-XX:G1HeapRegionSize\"手动指定Region大小,但是推荐默认的计算方式。
结构图
最终标记
筛选回收
算法:标记-复制
分类
YoungGC
MixedGC
Full GC
参数设置
G1优化建议
使用场景
1、50%以上的堆被存活对象占用
2、对象分配和晋升的速度变化非常大
3、垃圾回收时间特别长,超过1秒
4、8GB以上的堆内存(建议值)
5、停顿时间是500ms以内
每秒几十万并发的系统如何优化JVM
ZGC收集器
目标
支持TB量级的堆
最大GC停顿时间不超10ms
奠定未来GC特性的基础
最糟糕的情况下吞吐量会降低15%
存在问题
ZGC最大的问题是浮动垃圾
ZGC没有分代概念,每次都需要进行全堆扫描,导致一些“朝生夕死”的对象没能及时的被回收。
解决方案
GC调优
如何选择垃圾收集器
JDK 1.8默认使用 Parallel(年轻代和老年代都是)JDK 1.9默认使用 G1
jps
显示当前所有java进程
jmap
查看内存信息,实例个数以及占用内存大小
jstack
用jstack加进程id查找死锁
找出占用cpu最高的线程堆栈信息
jvisualvm
jinfo
查看正在运行的Java应用程序的扩展参数 查看jvm的参数
jstat
查看堆内存各部分的使用量,以及加载类的数量
垃圾回收统计
JVM运行情况预估
年轻代对象增长的速率
Young GC的触发频率和每次耗时
每次Young GC后有多少对象存活和进入老年代
Full GC的触发频率和每次耗时
优化思路
Arthas
内存溢出和内存泄漏
内存溢出(out of memory)
内存泄漏(memory leak)
Mysql性能调优
Sql执行原理详解
连接器详解
优化器详解
执行器详解
Innodb的BufferPool机制详解
Redo重做日志、Undo回滚日志与Binlog详解
索引底层剖析
数据结构角度
B+树索引
Hash索引
FULL TEXT索引
物理存储角度
聚簇索引
非聚簇索引
逻辑角度
主键索引
唯一索引
单列索引
多列索引
索引使用角度
覆盖索引
索引下推
执行计划与SQL优化
explain工具深度使用
阿里巴巴索引优化最佳实践
MySQL锁机制与事务隔离级别
MySQL锁
性能
乐观锁
悲观锁
操作
读锁
写锁
粒度
表锁
行锁
死锁以及优化解决
事务隔离级别
读未提交
读已提交
可重复读
序列化
MVCC多版本并发控制机制
Tomcat性能调优
Nginx调优
并发编程专题
操作系统内核原理
JMM内存模型
并发同步处理
并发包之tools限制
并发包之atomic原子操作
阻塞队列BlockingQueue详解
并发Map、List、Set详解
Executor线程池及核心源码解剖
ForkJoin框架详解
无锁并发框架Disruptor实战
框架源码专题
应用框架Spring
中文文档
Spring IOC 源码剖析
整体认知spring 体系结构
Spring IOC容器设计原理
bean生命周期
初始化InitializingBean/@PostConstruct
Bean的后置处理器BeanPostProcessor源码分析
销毁DisposableBean/@PreDestroy
Spring Context 装载过程源码分析
BeanFactoryPostProcessor源码分析
BeanDefinitionRegistryPostProcessor源码分析
Spring IOC 循环依赖问题源码深度剖析
Factorybean与Beanfactory区别
Spring AOP源码剖析
掌握Spring AOP 编程概念
AOP注解编程
@EnableAspectJAutoProxy
@Before/@After/@AfterReturning/@AfterThrowing/@Around
@Pointcut
基于Spring AOP 实现应用插件机制
Spring AOP源码分析
ProxyFactory源码解析
AOP代理源码解析
拦截器链与织入源码解析
Spring事务控制与底层源码分析
@EnableTransactionManagement源码剖析
@Transactional源码剖析
Spring MVC源码剖析
理解MVC设计思想
从DispatchServlet 出发讲述MVC体系结构组成
基于示例展开DispatchServlet 核心类结构
DispatcherServlet 中的 doDispatch 方法执行时,HandlerAdapter 的 handle 方法的返回值就是 ModelAndView,只有我们的控制器方法定义为 void时,才不会返回此类型。当返回值是 String 的时候也会创建 ModelAndView 并返回。
MVC初始化及执行流程源码深度解析
RequestMaping源码实现解析
熟悉MVC组件体系
映射器原理实现
执行适配器原理实现
Spring mvc 采用适配器模式来适配调用指定Handler
视图解析器原理实现
第一种:请求转发第二种:重定向第三种:直接使用 Response 对象获取流对象输入
异常捕捉器原理实现
Spring注解式开发
@Bean/@ComponentScan/@Configuration/@Conditional
@Component/@Service@/Controller/@Repository
@Lazy/@Scope/@Import/@Value/@Profile
@Autowired/@Resources/@Inject
Spring5新特性
新特性详解
响应式编程模型
函数式风格的ApplicationContext
Kotlin表达式的支持
SpringWebFlux模块讲解
Spring Security原理和源码解析
快速入门与高级应用
核心安全过滤器源码剖析
会话管理源码剖析
命名空间配置源码剖析
授权体系结构源码剖析
Outh1.0与Outh2.0协议详解
Spring Webflux详解
Webflux快速入门
响应式编程实战
JDK响应式流编程实战
Reactive Stream 响应式流详解
Webflux服务端开发详解
Webflux客户端声明式rest client框架开发讲解
ORM框架MyBatis
Mybatis 快速掌握
MyBatisHibernate及传统JDBC对比
Mybatis全局参数详解
详解configuration、properties、 settings、typeAliases、 mapper
掌握xml和annotations和Criteria差异
Mybatis 源码分析
整体认识mybatis源码结构
Mybatis核心应用配置与原理解析
Spring与MyBatis集成源码剖析
Configuration、Mapper、SqlSession、Executor源码解析
Mybatis徒手实现
熟悉MyBatis内部运行机制
熟悉MyBatis初始化过程
源码debug一行行详细讲解
MyBatis二级缓存应用
手写实现-套mybatis框架
学习源码中的优秀设计模式
设计原则
开闭、单-职责及里氏替换原则
依赖倒置。接口隔离、合成复用原则
迪米特法则
创建型模式
工厂方法、抽象工厂及单例模式
建造者与原型模式
行为型模式
模板方法,策略及观察者模式
迭代器、责任链、命令及中介者模式
备忘录,状态访问者及解释器模式
结构型模式
适配器、装饰器及代理模式
外观、桥接、组合及享元模式
应用场景
线程池的单例模式实现
电商优惠促销策略模式实现
AOP底层代理模式实现
RedisTemplate、JdbcTemplate模板模式实现
Zookeeper监听器观察者模式实现
微服务网关鉴权责任链模式实现
多级缓存架构装饰器模式实现
分布式框架专题
分布式消息中间件
RabbitMQ
RocketMQ
KafKa
分布式存储中间件
Redis
MongoDB
FastDFS
ElasticSearch
分布式框架
Zookeeper
Dubbo
ShardingSphere
Netty
微服务系列专题
微服务架构变迁史
淘宝电商微服务架构变迁史
京东电商微服务架构变迁史
SpringBoot详解及源码解剖
Spring boot 快速开始及核心配置详解
Spring boot 部署方式及热部署详解
Web开发模板引擎Thymeleaf及Freemarker详解
Spring boot集成Mybatis,Redis,RabbitMq等三方框架
Spring boot启动过程源码分析
Spring boot自动装配源码分析
SpringCloud Alibaba详解及源码解剖
SpringCloud Netflix详解及源码解剖
项目实战专题
亿级流量微服务电商中台
BAT内部自研分布式调用链中间件
互联网工具专题
Git
Maven
Jenkins
Linux
虚拟容器
Docker
Kubernetes
拓展技术专题
面试专题
算法与数据结构
区块链技术(Java版)
大数据技术
人工智能技术
0 条评论
下一页