当前位置: 首页 > news >正文

JVM实战(19)——JVM调优工具概述

作者简介:大家好,我是smart哥,前中兴通讯、美团架构师,现某互联网公司CTO

联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬

学习必须往深处挖,挖的越深,基础越扎实!

阶段1、深入多线程

阶段2、深入多线程设计模式

阶段3、深入juc源码解析

阶段4、深入jdk其余源码解析

阶段5、深入jvm源码解析

一、简介

前面章节,我们已经介绍了如何通过GC日志去分析系统的运行情况。本章,我们将带领大家运行一些JVM调优/检测工具来分析运行中的系统。我们常用的调优/检测工具有三种:jstatjmapjhat,我们来一一看下。

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]:操作参数
  • LVMID:JVM进程ID
  • [interval]:连续输出的时间间隔
  • [count]:连续输出的次数

接下来,我们就介绍jstat的一些常用命令。

2.2 jstat -gc PID

jstat -gc PID,该命令可以查看JVM的内存和GC情况,PID就是JVM的进程ID。运行命令后可以看到如下信息:

S0C:From Survivor区的总大小
S1C:To Survivor区的总大小
S0U:From Survivor区目前已使用空间
S1U:To Survivor区目前已使用空间
EC:Eden区的总大小
EU:Eden区目前已使用空间
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 基本用法

jmap(JVM 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,format=b,file=dump.hprof PID,这个命令会在当前目录下生成一个dump.hprof二进制文件,它会把这一时刻Java堆内存中的所有对象的快照放到文件中去,供后续分析。

四、jhat

jhat(JVM 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端口时,就可以通过图形化的方式去分析堆内存里的对象分布情况了。

五、总结

本章,我们介绍了jstatjmapjhat这三种命令行工具的基本用法。系统开发完毕后,一般要经过 预估性优化 、 压测优化 、 线上监控 这三个过程。

预估性优化 :本质就是 估算系统内存使用模型,然后合理分配Java堆内存,尽量让每次Young GC后的存活对象小于Survivor区,避免存活对象频繁进入老年代引发Full GC 。

压测优化 :是对预估性优化的检验,通常这个环境会使用一些压测工具模拟高并发的访问,看看系统能否撑住请求压力、响应延时是否在正常范围内,保持稳定运行。压测环节需要借助jstat等工具分析JVM运行情况,然后合理调整堆内存分布。

线上监控 :是系统上线之后对JVM的监控,最简单的方式是在每天的高峰期和日常期,用jstatjmapjhat等命令查看JVM情况。更常见的做法是引入专门的监控系统,比如Zabbix、OpenFalcon、Ganglia等。业务系统会将JVM统计项发给这些监控系统,然后监控系统会进行分析并以图形化方式动态展现,还可以制定监控规则,让其对频繁GC的情况进行告警。

下一章,我们将通过实际案例讲解如何通过jstatjmapjhat这三种命令行工具进行优化。

相关文章:

JVM实战(19)——JVM调优工具概述

作者简介:大家好,我是smart哥,前中兴通讯、美团架构师,现某互联网公司CTO 联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬 学习必须往深处挖&…...

Windows10无法访问github

亲测有效 1、修改hosts文件 如果电脑是Windows系统:打开 C:\Windows\System32\drivers\etc 找到hosts文件,将对应的Host地址修改为: #github 140.82.112.4 github.com 199.232.69.194 github.global.ssl.fastly.net 如果在保存hosts时遇到…...

GIT 分支管理办法(二)

GIT 分支管理办法(二) 一. 大型项目分支管理中存在的痛点 大型项目中需求的上线存在很大的不确定性,而且往往存在多版本、多团队、多开发并行的情况。尤其是大型企业对上线分支中编号的管理十分严苛,严禁夹带上线。这时对于开发…...

Vue面试之Mixins

Vue面试之Mixins 定义Mixins使用Mixins全局MixinsMixins合并策略注意事项命名冲突:过度使用 最近在整理一些前端面试中经常被问到的问题,分为vue相关、react相关、js相关、react相关等等专题,可持续关注后续内容,会不断进行整理~ …...

YOLOv8改进 | 主干篇 | EfficientViT高效的特征提取网络完爆MobileNet系列(轻量化网络结构)

一、本文介绍 本文给大家带来的改进机制是主干网络,一个名字EfficientViT的特征提取网络(和之前发布的只是同名但不是同一个),其基本原理是提升视觉变换器在高效处理高分辨率视觉任务的能力。它采用了创新的建筑模块设计,包括三明治布局和级联…...

分布式限流要注意的问题

本文已收录至我的个人网站:程序员波特,主要记录Java相关技术系列教程,共享电子书、Java学习路线、视频教程、简历模板和面试题等学习资源,让想要学习的你,不再迷茫。 为什么需要匀速限流 同学们回想一下在Guava小节里…...

git将一个远程分支的部分修改提交到另一个远程分支

将一个远程分支的部分修改提交到另一个远程分支 将一个远程分支的部分修改提交到另一个远程分支,可以使用 git cherry-pick 命令。这个命令可以选择特定的提交(commit)从一个分支应用到另一个分支。 切换到目标本地分支: 首先&am…...

promise是什么怎么使用

Promise 是一种 JavaScript 中的对象,用于处理异步操作。它表示一个最终可能完成(解析)或失败(拒绝)的操作,以及其结果值。 Promise 有三种状态: Pending(待定)&#x…...

国际版WPS Office 18.6.1

【应用名称】:WPS Office 【适用平台】:#Android 【软件标签】:#WPS 【应用版本】:18.6.1 【应用大小】:160MB 【软件说明】:软件日常更新。WPS Office是使用人数最多的移动办公软件。独有手机阅读模式…...

记录一次数据中包含转义字符\引发的bug

后端返回给前端的数据是: { "bizObj": { "current": 1, "orders": [ ], "pages": 2, "records": [ { "from": "1d85b8a4bd33aaf99adc2e71ef02960e", …...

网络协议:ICMP协议及实用工具介绍

目 录 一、ICMP介绍 1、概述 2、功能 3、特点 二、ICMP的数据报文 三、ICMP相关工具 四、主要ICMP工具应用 1、Ping 2、Traceroute (1) 方法1: (2)方法2: 3、Nmap 一、ICMP介绍 1、概述 …...

Hyper-V如何设置网络-虚拟交换机设置

Hyper-V如何设置网络-虚拟交换机设置 缘起虚拟交换机类型1. 外部交换机;2. 内部交换机;3. 专用交换机;4.default switch; 虚拟机上openwrt多种网络连接方式 缘起 发现win10还有个虚拟机Hyper-V的功能,不太占资源&…...

SAP不同语言开发

文章目录 1 Please write English Nmae2 go to goto menu and translation3 Write your target language .4 Please input Chinese5 Summary 1 Please write English Nmae 2 go to goto menu and translation 3 Write your target language . 4 Please input Chinese 5 Summary…...

瑞_Java开发手册_(一)编程规约

文章目录 编程规约的意义(一)命名风格(二)常量定义(三)代码格式(四)OOP 规约(五)日期时间(六)集合处理(七)并发…...

【JVM】本地方法接口 Native Interface

一、JNI简介 JVM本地方法接口(Java Native Interface,JNI)是一种允许Java代码调用本地方法(如C或C编写的方法)的机制。这种技术通常用于实现高性能的计算密集型任务,或者与底层系统库进行交互。 二、JNI组…...

JS 本地存储 sessionStorage localStorage

本地存储 随着互联网的快速发展,基于网页的应用越来越普遍,同时也变的越来越复杂,为了满足各种各样的需求,会经常性在本地存储大量的数据,HTML5规范提出了相关解决方案。 本地存储特性 1、数据存储在用户浏览器中 2…...

K8S 存储卷

意义:存储卷----数据卷 容器内的目录和宿主机的目录进行挂载 容器在系统上的生命周期是短暂的,delete,k8s用控制器创建的pod,delete相当于重启,容器的状态也会回复到初始状态 一旦回到初始状态,所有的后天编辑的文件…...

一个SqlSugar实际案例

SqlGugar是一个非常好的数据库操作框架,今天用一个示例来分享如何使用。 新建一张课程表 结构如下: CREATE TABLE t_course (id int NOT NULL AUTO_INCREMENT COMMENT ID,title varchar(1024) NOT NULL COMMENT 课程标题,description text NOT NULL C…...

【RT-DETR有效改进】ShapeIoU、InnerShapeIoU关注边界框本身的IoU(包含二次创新)

前言 大家好,我是Snu77,这里是RT-DETR有效涨点专栏。 本专栏的内容为根据ultralytics版本的RT-DETR进行改进,内容持续更新,每周更新文章数量3-10篇。 专栏以ResNet18、ResNet50为基础修改版本,同时修改内容也支持Re…...

从理论到实践:数字孪生技术的全面应用探讨

数字孪生是一种将实际物体或系统的数字模型与其实时运行状态相结合的概念。这一概念的核心在于创建一个虚拟的、与真实世界相对应的数字副本,以便监测、分析和优化实体系统的性能。 简单理解,数字孪生就是在一个设备或系统的基础上,创造一个…...

springboot 百货中心供应链管理系统小程序

一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,百货中心供应链管理系统被用户普遍使用,为方…...

可靠性+灵活性:电力载波技术在楼宇自控中的核心价值

可靠性灵活性:电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中,电力载波技术(PLC)凭借其独特的优势,正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据,无需额外布…...

OkHttp 中实现断点续传 demo

在 OkHttp 中实现断点续传主要通过以下步骤完成,核心是利用 HTTP 协议的 Range 请求头指定下载范围: 实现原理 Range 请求头:向服务器请求文件的特定字节范围(如 Range: bytes1024-) 本地文件记录:保存已…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放

简介 前面两期文章我们介绍了I2S的读取和写入,一个是通过INMP441麦克风模块采集音频,一个是通过PCM5102A模块播放音频,那如果我们将两者结合起来,将麦克风采集到的音频通过PCM5102A播放,是不是就可以做一个扩音器了呢…...

Spring Boot面试题精选汇总

🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...

【C语言练习】080. 使用C语言实现简单的数据库操作

080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...

代理篇12|深入理解 Vite中的Proxy接口代理配置

在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...

html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码

目录 一、👨‍🎓网站题目 二、✍️网站描述 三、📚网站介绍 四、🌐网站效果 五、🪓 代码实现 🧱HTML 六、🥇 如何让学习不再盲目 七、🎁更多干货 一、👨‍&#x1f…...

探索Selenium:自动化测试的神奇钥匙

目录 一、Selenium 是什么1.1 定义与概念1.2 发展历程1.3 功能概述 二、Selenium 工作原理剖析2.1 架构组成2.2 工作流程2.3 通信机制 三、Selenium 的优势3.1 跨浏览器与平台支持3.2 丰富的语言支持3.3 强大的社区支持 四、Selenium 的应用场景4.1 Web 应用自动化测试4.2 数据…...

掌握 HTTP 请求:理解 cURL GET 语法

cURL 是一个强大的命令行工具,用于发送 HTTP 请求和与 Web 服务器交互。在 Web 开发和测试中,cURL 经常用于发送 GET 请求来获取服务器资源。本文将详细介绍 cURL GET 请求的语法和使用方法。 一、cURL 基本概念 cURL 是 "Client URL" 的缩写…...