JVM 学习
基础篇
Java 支持跨平台
字节码文件详解
1、 应用场景
版本冲突、系统升级
2、字节码 文件的组成
3、 打开 class字节码文件
4、 基础信息
解决版本不兼容
52-44=8 —>>>JDK8
RandomStringUtils 该字节码文件版本:1.8
运行时环境:JDK6 1.6
5、常量池
6、方法
7、 查看字节码 工具
8、arthas
类加载
1、类的生命周期— 应用场景
2、 加载阶段
3、连接阶段
验证
准备
final 修饰的变量
初始化
运行时 数据区
1、应用场景
2、pc 程序计数器
3、栈
栈内存 也会溢出,stack over flow
4、堆内存
5、字符串 常量池
6、直接内存区域
总结:
垃圾回收
1、引用计数法
2、可达性 分析法
** GC Root 对象**
查看GC Root
3、软引用
四种引用:强弱软虚
强引用:永远不回收、
只有弱引用,没有其他 引用 指向该弱引用对象:GC触发就会回收,不管内存够不够
软引用:GC内存 不足时回收
调整 内存区域大小
对象在堆上的存储
JIT 即时编译器
ZGC
使用
实战篇
JVM实战篇工具
链接: https://pan.baidu.com/s/1KI04E4jNO4kAe9NlSreU4Q 提取码: yyds
Java 工具
内存调优
1、 内存泄露
2、Arthas 查看内存情况
3、 常见场景
内存泄露 常见场景
4、解决内存泄漏------->>>监控 top 命令
键盘按下 大写 M----->>>> 按照内存排序
5、解决内存泄漏------->>>监控 visual VM
6、 解决内存泄漏------->>>监控 arthas tunnel
<dependency><groupId>com.taobao.arthas</groupId><artifactId>arthas-spring-boot-starter</artifactId><version>3.7.1</version>
</dependency>
arthas:# tunnel地址,目前是部署在同一台服务器,正式环境需要拆分tunnel-server: ws://localhost:7777/ws# tunnel显示的应用名称,直接使用应用名app-name: ${spring.application.name}# arthas http访问的端口和远程连接的端口http-port: 8888telnet-port: 9999
部署 tunnel 服务端程序
nohup java -jar -Darthas.enable-detail-pages=true arthas-tunnel-server-3.7.1-fatjar.jar &
启动 Java应用
nohup java -jar -Dserver.port=8082 -Darthas.http-port=3662 -Darthas.telnet-port=8566 jvm-optimize-0.0.1-SNAPSHOT.jar &
查看 tunnel
7、 解决内存泄漏------->>>监控 Prometheus + Grafana 最终手段
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId><exclusions> <!-- 去掉springboot默认配置 --><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-logging</artifactId></exclusion></exclusions>
</dependency><!-- 暴露给 Prometheus --><dependency><groupId>io.micrometer</groupId><artifactId>micrometer-registry-prometheus</artifactId><scope>runtime</scope>
</dependency>
management:endpoint:metrics:enabled: true #支持metricsprometheus:enabled: true #支持Prometheusmetrics:export:prometheus:enabled: truetags:application: jvm-test #实例名采集endpoints:web:exposure:include: '*' #开放所有端口
阿里云
8、 内存泄露 原因------代码中的内存泄露
9、 内存溢出
还原 高并发请求导致的 内存溢出问题
启动程序
JMeter测试
10、内存溢出------>>> 诊断 MAT
** 打开 hprof 文件**
11、 服务器 ** 导出 运行中的系统的内存快照 并进行分析**
jmap -dump:live,format=b,file=/usr/local/jvm/dump/jmap.hprof 2544893
内存泄露检测
** 分析 超大堆的内存快照**
案例实战
12、 查询大数据量导致的 内存溢出
解决
13、Mybatis 导致的内存溢出
解决方案
将 IdList 放入Redis中,然后取出来,使用join() 方法,然后 传递字符串即可
String par=" (1,2,3,4,5)";
void search(String val);
// 传入par
// #{val} 接收即可
14、 K8S 环境导出大文件 导致内存溢出
15、 ThreadLocal 使用时 占用大量内存
注意!!!!
16、 接口导致的 内存溢出
设计 牛逼,防止丢失任务
** 队列 换成MQ 或者 Redis**
在线定位问题
**17、 btrace 和 arthas 在线定位问题 **
** 按照 目录进行放置 **
** 步骤 **
stack 类名 方法名
GC 调优
核心 指标
本地 安装 插件
Visual VM
Prometheus + Grafana
常见的 GC 模式
常见 JVM 参数设置
1、 Xms Xmx
2、 MaxMetaSpaceSize
3、Xss 虚拟机栈 大小
4、不建议 手动设置
垃圾回收器调优
parNew +CMS
G1
优化 垃圾回收器参数
实战:内存调优和GC调优
** 在线分析 HeapDump 文件**
总结
性能问题 发现与解决
** 1、 CPU 占用很高 **
然后去 文件中搜索即可
在线分析
** 2、 接口 响应时间很长的 定位**
stop 结束监控
** 3、 火焰图 定位接口 响应时间长**
# 启动 arthas
java -jar arthas.jar
# 执行监控
profile start # 生成 火焰图
profile stop --format html
** 4、 死锁问题的 检测 **
5、 基准 测试框架 JMH
JMH 介绍
环境搭建
mvn archetype:generate \
-DinteractiveMode=false \
-DarchetypeGroupId=org.openjdk.jmh \
-DarchetypeArtifactId=jmh-java-benchmark-archetype \
-DgroupId=org.sample \
-DartifactId=test \
-Dversion=1.0
<properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><jmh.version>1.37</jmh.version><javac.target>1.8</javac.target><uberjar.name>benchmarks</uberjar.name>
</properties>
一些问题
** 6、 性能调优实战**
** 优化前 **
** 优化后 **
总结