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

JVM工具

首先,JDK 自带了很多监控工具,都位于 JDK 的 bin 目录下,其中最常用的是 jconsole 和 jvisualvm 这两款视图监控工具。

一、jps(Java Process Status)

用于查看有权访问的虚拟机的进程,并显示他们的进程号
-v:列出虚拟机进程启动时的 JVM 参数。比如:-Xms20m -Xmx50m 是启动程序指定的 jvm 参数

二、jstat(JVM Statistics Monitoring Tool)

可以用来监视 JVM 内存内的各种堆和非堆的大小及其内存使用量、类装载、垃圾收集、JIT 编译等运行数据

jstat - [-t] [-h] [ []]

-gc:显示堆各分区大小、YGC,FGC次数和时长。包括 Eden 区、两个 Survivor 区、老年代、永久代等的容量、已用空间、GC 时间合计等信息
-gccapacity:显示内容与 -gc 基本相同,但输出主要关注 Java 堆各个区域使用到的最大、最小空间
-gcutil:显示内容与 -gc 基本相同,但输出主要关注已使用空间占总空间的百分比
-gccause:与 -gcutil 功能一样,但是会额外输出导致最后一次或当前正在发生的 GC 产生的原因
-gcnew:显示新生代 GC 状况
-gcnewcapacity:显示内容与 -gcnew 基本相同,输出主要关注使用到的最大、最小空间
-geold:显示老年代 GC 状况
-gcoldcapacity:显示内容与 -gcold 基本相同,输出主要关注使用到的最大、最小空间
-gcpermcapacity:显示永久代使用到的最大、最小空间

interval 参数:用于指定输出统计数据的周期,单位为毫秒。即:查询间隔
count 参数:用于指定查询的总次数

OOM案例:比较GC时长(GCT列)占运行市场的比例:
如果该比例超过 20%,则说明目前堆的压力较大;
如果该比例超过 98%,则说明这段时期内几乎一直在GC,堆里几乎没有可用空间,随时都可能抛出 OOM 异常

内存泄露案例
每隔一段较长的时间采样多组 OU(老年代内存量) 的最小值,如果这些最小值在上涨,说明无法回收对象在不断增加,可能是内存泄漏导致的。
在长时间运行的 Java 程序中,我们可以运行 jstat 命令连续获取多行性能数据,并取这几行数据中 OU 列(Old Used,已占用的老年代内存)的最小值
然后,我们每隔一段较长的时间重复一次上述操作,来获得多组 OU 最小值。
如果这些值呈上涨趋势,则说明该 Java 程序的老年代内存已使用量在不断上涨,这意味着无法回收的对象在不断增加,因此很有可能存在内存泄漏(不再使用的对象仍然被引用,导致GC无法回收)

三、jstack(JVM Stack Trace)

用于生成虚拟机指定进程当前时刻的线程快照(虚拟机堆栈跟踪)

参数:
-F 当正常输出的请求不被响应时,强制输出线程堆栈
-l 除堆栈外,显示关于锁的附加信息

线程快照:该进程内每条线程正在执行的方法堆栈的集合。
生成线程快照的作用:可用于定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待等问题。
这些都是导致线程长时间停顿的常见原因。当线程出现停顿时,就可以用 jstack 显示各个线程调用的堆栈情况。

在 thread dump 中,要留意下面几种状态

  • 死锁,Deadlock(重点关注)
  • 等待资源,Waiting on condition(重点关注)
  • 等待获取监视器,Waiting on monitor entry(重点关注)
  • 阻塞,Blocked(重点关注)
  • 执行中,Runnable
  • 暂停,Suspended
  • 对象等待中,Object.wait() 或 TIMED_WAITING
  • 停止,Parked

四、jmap(Memory Map)和jhat(Java Heap Analysis Tool)

jmap:打印出某个 JVM 进程内存内的所有对象的情况,一般用于查看内存占用情况。一般结合jhat使用

使用jmap -histo[:live] pid查看堆内存中的对象数目、大小统计直方图,如果带上live则只统计活对象,
jmap进行dump命令格式 jmap -dump:format=b,file=dumpFileName pid

五、Visual VM

六、jconsole:

一个 GUI 监视工具,可以以图表化的形式显示各种数据,并支持远程连接

http://www.lryc.cn/news/601177.html

相关文章:

  • 【优选算法】BFS解决FloodFill算法
  • Element表格单元格类名动态设置
  • VILA系列论文解读
  • 基于mnn架构在本地 c++运行llm与mllm模型
  • PostgreSQL AND OR 操作符详解
  • esp32s3创建rust工程 window成功mac
  • 前后端分离:架构模式与实践
  • Qt 分裂布局:QSplitter 使用指南
  • 四、搭建springCloudAlibaba2021.1版本分布式微服务-加入openFeign远程调用和sentinel流量控制
  • UNet 改进(38):融合多尺度输入与可变形卷积、门控特征融合的医学图像Unet分割网络
  • MySQL 事务和锁
  • 02人工智能中优雅草商业实战项目视频字幕翻译以及声音转译之以三方AI模型API制作方式预算-卓伊凡|莉莉
  • 车载诊断架构 ---面向售后的DTC应该怎么样填写?
  • KNN算法实战:手写数字识别详解
  • 前端基础班学习路线
  • Git+宝塔面板部署Hugo博客
  • net8.0一键创建辅助开发的个人小工具
  • 剑指offer第2版:双指针+排序+分治+滑动窗口
  • 零基础学习性能测试第五章:JVM性能分析与调优-GC垃圾分代回收机制与优化
  • 【嵌入式硬件实例】-555定时器调光电路实现
  • 工业控制系统安全之 Modbus 协议中间人攻击(MITM)分析与防范
  • DAY21-二叉树的遍历方式
  • 数据结构 堆(4)---TOP-K问题
  • Canvas实现微信小程序图片裁剪组件全攻略
  • mmap的调用层级与内核态陷入全过程
  • 六、搭建springCloudAlibaba2021.1版本分布式微服务-admin监控中心
  • 记录一次薛定谔bug
  • 基于LNMP架构的分布式个人博客搭建
  • Java大数据面试实战:Hadoop生态与分布式计算
  • 数据权属雷区:原始数据与衍生数据的法律边界如何划清?