JVM 下篇
2024-05-18 13:50:26 7 举报
AI智能生成
JVM 下篇
作者其他创作
大纲/内容
1-大厂面试题(见“JVM面试题”)
生产环境发生了内存溢出该如何处理?
生产环境应该给服务器分配多少内存合适?
如何对垃圾回收器的性能进行调优?
生产环境CPU负载飙高该如何处理?
生产环境应该给应用分配多少线程合适?
不加log,如何确定请求是否执行了某一行代码?
不加log,如何实时查看某个方法的入参与返回值?
1-生产环境中的问题
防止出现OOM
解决OOM
减少Full GC出现的频率
2-为什么要调优?
上线前
项目运行阶段
线上出现OOM
3-不同阶段的考虑
2-背景说明
运行日志
异常堆栈
GC日志
线程快照
堆转储快照
1-监控的依据
合理地编写代码
充分并合理的使用硬件资源
合理地进行JVM调优
2-调优的大方向
3-调优概述
介绍
GC频繁
cpu load过高
OOM
内存泄露
死锁
程序响应时间较长
第1步(发现问题):性能监控
打印GC日志,通过GCviewer或者 http://gceasy.io 来分析异常信息
灵活运用命令行工具、jstack、jmap、jinfo等
dump出堆文件,使用内存分析工具分析文件
使用阿里Arthas、jconsole、JVisualVM来实时查看JVM状态
jstack查看堆栈信息
第2步(排查问题):性能分析
适当增加内存,根据业务背景选择垃圾回收器
优化代码,控制内存使用
增加机器,分散节点压力
合理设置线程池线程数量
使用中间件提高程序效率,比如缓存、消息队列等
其他……
第3步(解决问题):性能调优
4-性能优化的步骤
1-停顿时间(或响应时间)
对单位时间内完成的工作量(请求)的量度
在GC中:运行用户代码的事件占总运行时间的比例(总运行时间:程序的运行时间+内存回收的时间)吞吐量为1-1/(1+n),其中-XX::GCTimeRatio=n
2-吞吐量
同一时刻,对服务器有实际交互的请求数
例如:1000个人同时在线,估计并发数在5%-15%之间,也就是同时并发量:50-150之间
3-并发数
Java堆区所占的内存大小
4-内存占用
吞吐量:每天通过高速公路收费站的车辆的数据(也可以理解为收费站收取的高速费)
并发数:高速公路上正在行驶的车辆的数目
响应时间:车速
起初车辆(并发数)比较少,提高车辆高速费能多收一点,车辆数目提高到一定程度再提高的话会导致车速过慢,甚至是拥堵,高速费自然就少了
以高速公路通行状况为例
5-相互之间的关系
5-性能评价/测试指标
第1章 概述篇
01-概述
类似Linux的ps命令
基本情况
测试
options参数
hostid参数(不建议使用,了解即可)
基本语法
02-jps:查看正在运行的Java进程
EC:Eden区的大小
EU:Eden区已使用的大小
S0C:幸存者0区的大小
S1C:幸存者1区的大小
S0U:幸存者0区已使用的大小
S1U:幸存者1区已使用的大小
MC:元空间的大小
MU:元空间已使用的大小
OC:老年代的大小
OU:老年代已使用的大小
CCSC:压缩类空间的大小
CCSU:压缩类空间已使用的大小
YGC:从应用程序启动到采样时young gc的次数
YGCT:从应用程序启动到采样时young gc消耗时间(秒)
FGC:从应用程序启动到采样时full gc的次数
FGCT:从应用程序启动到采样时的full gc的消耗时间(秒)
GCT:从应用程序启动到采样时gc的总时间
-gc
option参数
用于指定输出统计数据的周期,单位为毫秒。即:查询间隔
interval参数
用于指定查询的总次数
count参数
可以在输出信息前加上一个Timestamp列,显示程序的运行时间。单位:秒
经验
-t参数
可以在周期性数据输出时,输出多少行数据后输出一个表头信息
-h参数
补充
-class
-gccapacity
-gcutil
-gccause
-gcnew
-compiler
-printcompilation
-t
03-jstat:查看JVM统计信息
jinfo -sysprops PID (可以查看由System.getProperties()的取得的参数(当前进程对应系统的属性信息))
jinfo -flags PID (查看曾经赋值过的一些参数)
jinfo -flag 具体参数 PID (查看某个Java进程的具体参数的值)
查看
jinfo -flag [+-]具体参数 PID
针对boolean类型
jinfo -flag 具体参数=具体参数值 PID
针对非boolean类型
修改
java -XX:+PrintFlagsInitial (查看所有JVM参数启动的初始值)
java -XX:+PrintFlagsFinal (查看所有JVM参数的最终值)
java -XX:+PrintCommandLineFlags (查看哪些已经被用户或者JVM设置过的详细的XX参数的名称和值)
扩展
04-jinfo:实时查看和修改JVM配置参数
font color=\"#e74f4c\
手动的方式
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeampDumpPath=<filename.hprof>
自动的方式
使用1:导出内存映像文件
jmap -heap pid
jmap -histo pid
使用2:显示堆内存相关信息
jmap -permstat pid (查看系统的ClassLoader信息)
jmap -finalizerinfo (查看堆积在finalizerinfo 队列中的对象)
使用3:其它作用
小结(主要对手动方式说明)
05-jmap:导出内存映像文件&内存使用情况
06- jhat:JDK自带堆分析工具
(见视频P317)
07-jstack:打印JVM中线程快照
基本上集结了上面所有命令的功能
主要用 jcmd pid help 命令,查看有哪些参数可以用,再官网看这些参数是干嘛的
08-jcmd:多功能命令行
09-jstatd:远程主机信息收集
第2章 JVM监控及诊断工具-命令行篇
01-工具概述
基本概述
启动
三种连接方式
(见下图红框部分即代表其可以显示的所有项了)
主要作用
02-JConsole
插件的安装
连接方式
主要功能
就是前面学的命令集合,比如这里“概述”部分
死锁案例(此处截图已经不是上面那个代码)
03-Visual VM
dump文件内容
两点说明
获取dump文件
获取堆dump文件
展示了各个类的实例数目和这些实例的heap或Retainedheap的总和
histogram
查看系统中的Java线程
查看局部变量的信息
thread overview
ArrayList“with outgoing references”情况
with outgoing references
数组元素“with incoming references”情况
with incoming references
获得对象相互引用的关系
shallow heap
retained heap
具体计算公式见:https://blog.csdn.net/shangshanzixu/article/details/114828860?spm=1001.2014.3001.5501
案例
补充:对象实际大小
练习
案例分析:StudentTrace
浅堆与深堆
支配树
分析堆dump文件
说明
一般先看占用内存最大的对象,鼠标触碰到饼状图不同部分下面的深堆浅堆就会变化
鼠标左键单击,查看它引用了哪些对象
同理还是分析占用内存最多的对象
分析该对象
继续深入分析,此时查看的是value值,因为只有它是我们可以改变的,其它属性都不是我们所能左右的
之后查看它总数内存占多大(这里有个注意点:最好用OQL查该对象的总数,而不是看Total的值,其代表容器的容量的大小,因为map和数组等等结构都有自动扩容机制,实际对象数目很可能小于容器大小),及占用内存和当前堆内存大小的比例(它是不是占比很高)
查看其信息,创建时间到结束时间非常短,所以怀疑是短时间内创建大量session导致的,查看dump文件里的session数量
对所有session最初创建时间和最晚结束时间进行计算,验证我们的猜想
分析过程
案例:Tomcat堆溢出分析
支持使用OQL语言查询对象信息
04-eclipse MAT
内存泄漏的理解与分类
1-静态集合类
2-单例模式
3-内部类持有外部类
4-各种连接,如数据库连接、网络连接和IO连接等
5-变量不合理的作用域
案例1
案例2
6-改变哈希值
注意这里创建字符串要用new的方式创建,确保在堆中有对象指向常量池的字符串常量。因为垃圾回收器只会回收new String(\"obejct1\")所创建的String对象,而不会回收常量池中的字符串常量\"obejct1\"。常量池中的字符串常量通常在整个程序运行期间都是可用的。所以写成String ref1 = \"object1\"垃圾回收是不会成功的。
7-缓存泄漏
8-监听器和回调
Java中内存泄漏的8种情况
案例代码
分析
解决方法
案例2(移动端开发案例)
内存泄漏案例分析
补充1:再谈内存泄漏
SELECT子句
FROM子句
WHERE子句
内置对象与方法
补充2:支持 OQL 语言查询对象信息
特点
下载与安装
JProfiler中配置IDEA
方式一
方式二
下载插件两种方式
IDEA集成JProfiler
安装与配置
如何选择:①如果是堆内存泄漏OOM的分析,Sampling模式完全可以完成该工作,就不要用重构模式了 ②如果是正在运行的程序也不要用重构模式
Instrumentation重构模式
Sampling抽样模式
数据采集方式
记录对象和数组的数目
遥感监测 Telemetries
下面“All Objects”视图可以挖掘的信息/着重关注的信息
许多加了“”双引号的都是属于前面某张截图的内容,建议结合看,不然会有点懵,如“分析”,就是上图里“分析”部分的内容
该功能会急剧降低程序性能,所以只有怀疑有内存泄漏要分析才用,平时就关闭
已经怀疑到某个对象泄漏问题了,则可以继续进行下面的堆内存追踪
内存视图 Live Memory
图表的引用关系确实更加清晰
图中这个保存快照的方法只能存储为html或者csv文件,内容感觉好少不友好,使用ctrl+shift+s或者选择菜单栏“Profiling”->“Save HPROF snapshot”转储快照hprof文件内容很友好,但它的缺点是保存的是当前时刻的快照
堆遍历 heap walker
cpu视图 cpu views
线程视图 thread
监控和锁 Monitors &Locks
具体使用
如下每次GC完剩余内存不是增长趋势说明正常
案例1(正常情况)
这里的内存溢出告诉我们静态集合容易出现问题,慎用!!!
下图可以看到GC是正常有执行,但GC后的剩余内存总体是增加的,查看类的实例个数也是不会降下来的,说明内存溢出
案例2(内存溢出)
案例分析
05-JProfiler
具体看官网:https://arthas.aliyun.com/doc/commands.html
相较于上面工具的优点
安装与使用
相关诊断指令
06-Arthas
历史
概述
功能:实时监控JVM运行时的状态
Java Flight Recorder
07-Java Mission Control
使用场景:一般我们是面向接口编程,随着业务的发展,甲方发现接口不稳定,或者性能不好。为了改善接口性能,先要找到性能瓶颈就可以用它
Flame Graphs(火焰图)
Tprofiler
Btrace
TourKit
JProbe
Spring Insight
08-其它工具
自己的总结:无论哪款工具常用的也就是内存方面的功能,如果要分析内存泄漏还需要分析堆方面的内容。其它功能如方法执行慢看CPU方面功能,线程问题(死锁等等)看线程方面功能。如Profiler对应常用的功能
第3章 JVM监控及诊断工具-GUI篇
类型一:标准参数选项
类型二:-X参数选项
类型三:-XX参数选项
01-JVM参数选项类型
jinfo能修改的参数具体见“第2章 JVM监控及诊断工具-命令行篇” -> “04-jinfo:实时查看和修改JVM配置参数” -> “基本语法” -> “修改”
02-添加JVM参数选项
打印设置的XX选项及值(查)
堆、栈、方法区等内存大小设置
OutOfMemory相关的选项
复习
-XX:+PrintCommandLineFlags 输出
查看默认垃圾回收器
Serial回收器
ParNew回收器
补充参数
特别说明
CMS回收器
Mixed GC调优参数
G1回收器
怎么选择垃圾回收器
垃圾收集器相关选项
常用参数
其它参数
GC日志相关选项
第二三个命令是针对代码缓存大小,即JIT会将代码缓存起来的大小,如果这个缓存满了,就只能走解释器,解释器执行速度较慢
面试题:什么是TLAB,TLAB有什么用。最后一个设置TLAB大小,其是为了解决多个线程访问堆空间的问题,如果多个线程访问Edge区为了保证安全性需要加锁,加锁效率就低了,所以在Edge区为每个线程分配一份TLAB,届时每个线程用自己的TLAB访问堆空间就能解决安全问题,还能提高效率/吞吐量
03-常用的JVM参数选项
04-通过Java代码获取JVM参数
第4章 JVM运行时参数
01-GC日志参数
需要区分Full GC和Major GC
日志文件能够很好体现用的什么GC
复习:GC分类
MinorGC
FullGC
GC日志分类
垃圾收集器
GC前后情况
GC时间
GC日志结构剖析
解析
MinorGC日志解析
FullGC日志解析
02-GC日志格式
GCeasy
安装
GCViewer
官网上没有下载的地方,需要自己从SVN上拉下来编译
不过这个工具似乎没怎么维护了,存在不少bug
GChisto
工具很强大,但只能打开由以下参数生成的GC log,-verbose:gc -Xloggc:gc.log。添加其它参数生成的gc.log无法打开
HPjmeter集成了以前的HPjtune功能,可以复习在HP机器上产生的垃圾回收日志文件
HPjmeter
其他工具
03-GC日志复习工具
第5章 分析GC日志
案例1:堆溢出
案例2:元空间溢出
案例3:GC overhead limit exceeded
案例4:线程溢出
第6章 OOM常见各种场景及解决方案
2-调优基本问题
1-概述篇
面试题
OOM案例1:堆溢出
如果是远程查看只能用命令jstat判断了
OOM案例2:元空间溢出
OOM案例3:GC overhead limit exceeded
OOM案例4:线程溢出
2-OOM案例
性能优化工具Jmeter
案例1:调整堆大小提高服务的吞吐量
案例2:调整垃圾回收器提高服务的吞吐量
案例3: JVM优化之JT优化
案例4: G1并发执行的线程数对性能的影响
案例5:合理配置堆内存
特殊问题:新生代与老年代的比例
案例6: CPU占用很高排查方案
日均百万级订单交易系统如何设置JVM参数
第7章 性能优化案例
1.prof文件不会覆盖,即会保留之前的文件,而log文件会进行覆盖操作。
2.prof(dump)文件会随着程序运行越来越大,我们可以定期清理再生成新的prof文件。log文件可以修改为追加写入(覆盖写不好),也是定期清理比较好
注意
JVM 下篇
0 条评论
回复 删除
下一页