网站如何做数据储存的,南京核酸最新通知,做网站主要学什么条件,青岛行业网站建设电话作者简介#xff1a;大家好#xff0c;我是smart哥#xff0c;前中兴通讯、美团架构师#xff0c;现某互联网公司CTO 联系qq#xff1a;184480602#xff0c;加我进群#xff0c;大家一起学习#xff0c;一起进步#xff0c;一起对抗互联网寒冬 学习必须往深处挖… 作者简介大家好我是smart哥前中兴通讯、美团架构师现某互联网公司CTO 联系qq184480602加我进群大家一起学习一起进步一起对抗互联网寒冬 学习必须往深处挖挖的越深基础越扎实
阶段1、深入多线程阶段2、深入多线程设计模式阶段3、深入juc源码解析阶段4、深入jdk其余源码解析阶段5、深入jvm源码解析
一、简介
前面章节我们已经介绍了如何通过GC日志去分析系统的运行情况。本章我们将带领大家运行一些JVM调优/检测工具来分析运行中的系统。我们常用的调优/检测工具有三种jstat、jmap、jhat我们来一一看下。
jstat(JVM statistics Monitoring)用于 监视JVM运行时状态信息 的命令它可以显示出虚拟机进程中的类装载、内存、垃圾收集、JIT编译等运行数据。
jmap(JVM Memory Map)用于生成 heap dump 文件jmap可以查询当前Java堆内存的详细信息比如当前各个区域使用率总容量、已使用、未使用、当前使用的是哪种收集器等。
jhat(JVM Heap Analysis Tool)一般与jmap搭配使用用来 分析jmap生成的dump文件 jhat内置了一个微型的HTTP/HTML服务器生成dump的分析结果后可以在浏览器中查看。 当然除了上述介绍的最基本的工具外还有很多图形化的工具比如VisualVM、MAT等等。我们的目的是介绍使用这些工具进行调优的思路在理解了思想之后运用任何工具都可以轻松把JVM的运行情况分析清楚一通百通。 二、jstat
jstat可以检查JVM的整体运行情况包括JVM内的Eden、Survivor、老年代的内存使用情况以及Young GC和Full GC的频率及耗时。通过这些指标我们可以分析当前系统的运行状况判断当前系统的内存使用压力、GC频次是否太高、内存分配是否合理。 2.1 基本用法
jstat的基本用法如下
jstat [option] LVMID [interval] [count]
[option]操作参数LVMIDJVM进程ID[interval]连续输出的时间间隔[count]连续输出的次数
接下来我们就介绍jstat的一些常用命令。 2.2 jstat -gc PID
jstat -gc PID该命令可以查看JVM的内存和GC情况PID就是JVM的进程ID。运行命令后可以看到如下信息
S0CFrom Survivor区的总大小 S1CTo Survivor区的总大小 S0UFrom Survivor区目前已使用空间 S1UTo Survivor区目前已使用空间 ECEden区的总大小 EUEden区目前已使用空间 OC老年代的总大小 OU老年代目前已使用空间 MC方法区永久代、元数据区的总大小 MU方法区永久代、元数据区目前已使用空间 YGC系统运行迄今为止的Young GC次数 YGCT系统运行迄今为止的Young GC总耗时 FGC系统运行迄今为止的Full GC次数 FGCT系统运行迄今为止的Full GC总耗时 GCT系统运行迄今为止的所有GC总耗时 jstat -gc PID是最常用的命令基本足够我们分析JVM的运行情况jstat还有许多其它命令读者可以参考Oracle官方文档 https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jstat.html 。 2.3 分析思路
当我们使用jstat来分析JVM的运行情况时我们最关注以下信息
新生代对象的增长速率Young GC的触发频率Young GC的耗时每次Young GC后的新生代存活对象大小每次Young GC后的晋升老年代对象大小老年代对象的增长速率Full GC的触发频率Full GC的耗时
只要知道了这些信息就可以结合前几章的分析方法对JVM优化合理分配内存空间减少新生代对象频繁进入老年代避免频繁Full GC。 新生代对象的增长速率
根据前面几章的案例分析我们首先需要对系统的内存使用模型进行估算也就是分析 每秒钟会在Eden分配多少对象 。
可以通过 jstat -gc PID 1000 10 进行分析即每隔1s更新一行jstat统计信息一共执行10次。
举个例子假如执行这个命令后第1s先显示出来Eden区使用了200MB内存第2s显示出来的那行统计信息里发现Eden区使用了205MB第3s显示出来的那行发现Eden区使用了209MB内存。以此类推可以推断出系统大概每秒新增5MB左右的对象。
另外一般系统有高峰和日常两种状态高峰时期执行上述命令可以看到高峰期的对象增长速率。非高峰期可能系统负载比较低不一定每秒都有请求所以可以把上面的1秒钟调整成1分钟甚至10分钟。
按照上述思路基本可以对线上系统的高峰和日常两个时段内的对象增长速率有很清晰的了解。 Young GC的触发频率
通过新生代对象的增长速率可以很容易推测出Young GC的触发频率。比如Eden区总共有800MB内存高峰期每秒新增5MB对象那么高峰期大概3分钟就会触发一次Young GC。日常期以次类推。 Young GC耗时
jstat -gc会告诉我们从JVM启动至今一共发生了多少次Young GC以及总耗时。比如系统运行了24小时后共发生了260次Young GC总耗时20s。那么平均下来每次Young GC大概就耗时几十毫秒的时间。 Young GC存活/晋升对象大小
每次Young GC过后有多少对象会存活下来这个没法直接看出来但是可以根据Young GC的触发频率推断出来。
比如我们可以每隔3分钟统计一次jstsat -g PID 180000 此时可以观察Eden、Survivor、老年代的已使用空间的变化情况。正常来说Eden区在经历Young GC后会从接近占满到变得很少Survivor区会放入一些存活对象老年代可能会增长一些对象占用。
所以每次Young GC过后的存活对象大小就是Survivor区的对象大小和本次老年代增长的大小晋升对象的大小就是本次老年代增长的大小。 Full GC的触发频率/耗时
只要知道了老年代的增长速率那么Full GC的触发时机就可以推断出来。比如老年代总共800MB内存每隔3分钟新增50MB那么大概1小时触发一次Full GC这就是Full的触发频率。
至于Full GC的平均耗时可以通过jstat命令打印出来的JVM启动以来的Full GC次数和总耗时计算出来。比如迄今一共执行了10次Full GC总耗时30s那么Full GC平均耗时就是3s左右。 三、jmap
如果只是需要了解JVM的运行情况然后进行JVM GC优化那jstat完全够用了。但是有时候我们会发现JVM新增对象的速度很快然后就想看看 到底什么对象占据了那么多的内存 。比如我们之前的模拟对象晋升一章中总有几百KB的未知对象占据着空间jmap就可以帮助我们解决这个问题。 3.1 基本用法
jmapJVM Memory Map用于生成 heap dump 文件可以查询当前Java堆的详细信息比如当前各个区域使用率总容量、已使用、未使用、当前使用的是哪种收集器等。其基本用法如下
jmap [option] LVMID
*[options]*命令参数
dump生成堆转储快照finalizerinfo显示在F-Queue队列等待Finalizer线程执行finalizer方法的对象heap显示Java堆详细信息histo显示堆中对象的统计信息permstat打印永久代元数据区、方法区中的F当dump没有响应时强制生成dump快照 3.2 jmap -heap PID
该命令用于显示Java堆内存的详细信息比如Eden区总容量、已使用的容量、剩余容量两个Survivor区的总容量、已使用容量、剩余容量老年代的总容量、已使用容量、剩余容量。
但是这些信息一般jstat命令就可以显示所以一般不会用jmap去看这些信息。 3.3 jmap -histo PID
jmap -histo会打印出类似以下的信息即当前JVM中的对象占用情况按空间占用从大到小排序 所以通过该命令可以了解到当前内存里到底是哪个对象占用了大量空间 3.4 jmap -dump PID
jmap -dump可以生成一个Java堆转储快照。比如jmap -dump:live,formatb,filedump.hprof PID这个命令会在当前目录下生成一个dump.hprof二进制文件它会把这一时刻Java堆内存中的所有对象的快照放到文件中去供后续分析。 四、jhat
jhatJVM Heap Analysis Tool一般与jmap搭配使用用来 分析jmap生成的Java堆转储快照文件 。
jhat内置了一个微型的HTTP/HTML服务器生成dump的分析结果后可以在浏览器中查看。 一般不会直接在服务器上进行分析因为jhat是一个耗时并且耗费硬件资源的过程一般把服务器生成的dump文件复制到本地或其他机器上进行分析。另外分析同样一个dump快照 MAT 需要的额外内存比jhat要小的多的多所以建议使用MAT来进行分析当然也看个人偏好。 4.1 基本用法
jstat的基本用法如下
jhat [dumpfile]
比如可以使用命令jhat dump.hprof -port 7000启动jhat服务器当通过浏览器访问7000端口时就可以通过图形化的方式去分析堆内存里的对象分布情况了。 五、总结
本章我们介绍了jstat、jmap、jhat这三种命令行工具的基本用法。系统开发完毕后一般要经过 预估性优化 、 压测优化 、 线上监控 这三个过程。
预估性优化 本质就是 估算系统内存使用模型然后合理分配Java堆内存尽量让每次Young GC后的存活对象小于Survivor区避免存活对象频繁进入老年代引发Full GC 。
压测优化 是对预估性优化的检验通常这个环境会使用一些压测工具模拟高并发的访问看看系统能否撑住请求压力、响应延时是否在正常范围内保持稳定运行。压测环节需要借助jstat等工具分析JVM运行情况然后合理调整堆内存分布。
线上监控 是系统上线之后对JVM的监控最简单的方式是在每天的高峰期和日常期用jstat、jmap、jhat等命令查看JVM情况。更常见的做法是引入专门的监控系统比如Zabbix、OpenFalcon、Ganglia等。业务系统会将JVM统计项发给这些监控系统然后监控系统会进行分析并以图形化方式动态展现还可以制定监控规则让其对频繁GC的情况进行告警。
下一章我们将通过实际案例讲解如何通过jstat、jmap、jhat这三种命令行工具进行优化。