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、 性能调优实战**



** 优化前 **

** 优化后 **

总结

