精选文章 JDK 14 里的调试神器了解一下?

JDK 14 里的调试神器了解一下?

作者:程序猿DD_ 时间: 2020-07-24 05:01:00
程序猿DD_ 2020-07-24 05:01:00

点击上方蓝色“程序猿DD”,选择“设为星标”

回复“资源”获取独家整理的学习资料!

JDK 14 里的调试神器了解一下?1

来源 | 8rr.co/z4R2

jcmd是JDK自带的调试工具,具有非常强大的功能。jcmd是JDK7中正式引入的,有了jcmd,完全可以替换很多常用的其他工具,比如jstak和jmap。

jcmd可以将具体的诊断命令发送给JVM。为了安全起见,使用jcmd的用户必须跟运行的java程序具有同样的用户和用户组。

jcmd的调试命令有很多种,每一种调试命令又有自己的参数。

本文将会结合具体的例子详细讲解jcmd的使用。

jcmd的语法

jcmd的语法比较简单:

jcmd [pid | main-class] command... | PerfCounter.print | -f filename


jcmd [-l]


jcmd -h

pid和main-class是二选一:

其中pid表示要发送诊断命令的java进程id。

也可以指定main-class,表示要发送诊断命令给运行该main-class的java进程。

command表示可以在jcmd中运行的命令,我们看下jcmd支持哪些命令:

./jcmd 93989 help
93989:
The following commands are available:
Compiler.CodeHeap_Analytics
Compiler.codecache
Compiler.codelist
Compiler.directives_add
Compiler.directives_clear
Compiler.directives_print
Compiler.directives_remove
Compiler.queue
GC.class_histogram
GC.class_stats
GC.finalizer_info
GC.heap_dump
GC.heap_info
GC.run
GC.run_finalization
JFR.check
JFR.configure
JFR.dump
JFR.start
JFR.stop
JVMTI.agent_load
JVMTI.data_dump
ManagementAgent.start
ManagementAgent.start_local
ManagementAgent.status
ManagementAgent.stop
Thread.print
VM.class_hierarchy
VM.classloader_stats
VM.classloaders
VM.command_line
VM.dynlibs
VM.events
VM.flags
VM.info
VM.log
VM.metaspace
VM.native_memory
VM.print_touched_methods
VM.set_flag
VM.stringtable
VM.symboltable
VM.system_properties
VM.systemdictionary
VM.uptime
VM.version
help

Perfcounter.print表示要打印java进程暴露的performance counters。

  • -f filename表示从文本文件中读取要运行的命令。

  • -l 列出不是运行在docker中JVM。

  • -h 表示帮助。

下面我们举几个常用的例子。

列出运行的JVM

./jcmd -l
98109 jdk.jcmd/sun.tools.jcmd.JCmd -l

通过使用jcmd -l可以列出所有正在运行的JVM进程。跟jps是一样的。

打印stack信息

使用jcmd pid Thread.print -l可以打印出java程序的stack信息。其中-l表示输出java.util.concurrent的lock信息。

下面看个简单的例子:



./jcmd 93989 Thread.print -l


Full thread dump Java HotSpot(TM) 64-Bit Server VM (14.0.1+7 mixed mode, sharing):


Threads class SMR info:
_java_thread_list=0x00007fbeb1c4cb10, length=12, elements={
0x00007fbeb282a800, 0x00007fbeb282d800, 0x00007fbeb282e800, 0x00007fbeb2830800,
0x00007fbeb2831800, 0x00007fbeb2832000, 0x00007fbeb2833000, 0x00007fbeb3831000,
0x00007fbeb3822000, 0x00007fbeb3174000, 0x00007fbeb3815000, 0x00007fbeb226f800
}


"Reference Handler" #2 daemon prio=10 os_prio=31 cpu=0.64ms elapsed=8996.59s tid=0x00007fbeb282a800 nid=0x4703 waiting on condition  [0x000070000440d000]
   java.lang.Thread.State: RUNNABLE
  at java.lang.ref.Reference.waitForReferencePendingList(java.base@14.0.1/Native Method)
  at java.lang.ref.Reference.processPendingReferences(java.base@14.0.1/Reference.java:241)
  at java.lang.ref.Reference$ReferenceHandler.run(java.base@14.0.1/Reference.java:213)


   Locked ownable synchronizers:
  - None

打印heap info

使用jcmd pid GC.heap_info可以获得heap info。

./jcmd 93989 GC.heap_dump heap_dump.out
93989:
Dumping heap to heap_dump.out ...
Heap dump file created [27727979 bytes in 0.643 secs]

打印heap dump

如果想知道heap里面到底有什么,则可以通过下面的命令将heap dump出来:

./jcmd 93989 GC.heap_dump heap_dump.out
93989:
Dumping heap to heap_dump.out ...
Heap dump file created [27727979 bytes in 0.643 secs]

heap dump需要传入一个文件名,存放dump出来的信息。

统计heap使用情况

有时候我们需要统计一下heap中各个对象的使用情况,则可以下面方法:

./jcmd 93989 GC.class_histogram


93989:
 num     #instances         #bytes  class name (module)
-------------------------------------------------------
   1:         25826       11748304  [B (java.base@14.0.1)
   2:          2233        1971800  [I (java.base@14.0.1)
   3:          5154         614928  java.lang.Class (java.base@14.0.1)
   4:         24757         594168  java.lang.String (java.base@14.0.1)
   5:          4491         439432  [Ljava.lang.Object; (java.base@14.0.1)
   6:         13177         421664  java.util.concurrent.ConcurrentHashMap$Node (java.base@14.0.1)
   7:          5025         160800  java.util.HashMap$Node (java.base@14.0.1)
   8:          8793         140688  java.lang.Object (java.base@14.0.1)
   9:           212         103584  [Ljava.util.concurrent.ConcurrentHashMap$Node; (java.base@14.0.1)

上面的结果非常有用,在一些性能调试方法可以起到意想不到的作用。

JFR功能

jcmd还支持jfr功能。JFR的全称叫做Java Flight Recorder。你可以将其看做是JVM中一些事件的记录器。

jcmd还有很多其他的功能,大家可以多用多探索。

往期推荐

有理有据:一篇来自前端同学对后端接口的吐槽!

面试:如何决定使用 HashMap 还是 TreeMap?

面试:一个Java字符串到底有多少个字符?

后端开发必知必学的 Linux 命令行大全

扬言要干掉 RESTful API 的 GraphQL 是什么鬼?

扫一扫,关注我

一起学习,一起进步

JDK 14 里的调试神器了解一下?2

勿删,copyright占位
分享文章到微博
分享文章到朋友圈

您可能感兴趣

  • 工作流学习2(书本)

    1、流程引擎的创建。 1.1、ProcessEngineConfiguration的buildProcessEngine方法 使用ProcessEngineConfiguration的create方法可以得到ProcessEngineConfiguration的实例。ProcessEngineConfiguration中提供了一个buildProcessEngine方法,该方法返回一个Pro...

  • Yolo系列详解

    零、图像基本概念 图像表示为二维的矩阵  灰阶图像 0-255,0表示黑色,255表示白色,其余表示灰色。 图像的坐标轴   彩色图像  注意:颜色信息对于任务有时候有用,有时候没用。 一、什么是目标检测 目标检测是计算机视觉中的经典的原子问题,即通过输入的图像来完成物体的检测,它需要解决两个问题: 物体在哪里 物体是什么 目标检测算法的传统实现 sift hog 等算法。这些算法的...

  • 浅谈TCP优化

    很多人常常对TCP优化有一种雾里看花的感觉,实际上只要理解了TCP的运行方式就能掀开它的神秘面纱。Ilya Grigorik 在「High Performance Browser Networking」中做了很多细致的描述,让人读起来醍醐灌顶,我大概总结了一下,以期更加通俗易懂。 流量控制 传输数据的时候,如果发送方传输的数据量超过了接收方的处理能力,那么接收方会出现丢包。为了避免出现此类问...

  • 图神经网络越深,表现就一定越好吗?

    2020-08-01 03:01:24 编译 | 陈彩娴 编辑 | 丛 末 数十层甚至数百层神经网络的应用,是深度学习的重要标志之一。但现实情况却远非如此:比如今年被视作机器学习领域最火热的研究方向之一——图神经网络,大多数都只运用了寥寥几层网络。 一般思路里,我们会认为图神经网络越深,效果就会越好。然而,日前帝国理工学院教授Michael Bronstein 发出了灵魂拷问:图神经网络的深...

  • CAS存在的三大问题以及解决方案

    CAS的由来 在JDK 5之前Java语言是靠synchronized关键字保证同步的,这会导致有锁 锁机制存在以下问题: 在多线程竞争下,加锁、释放锁会导致比较多的上下文切换和调度延时,引起性能问题。 一个线程持有锁会导致其它所有需要此锁的线程挂起。 如果一个优先级高的线程等待一个优先级低的线程释放锁会导致优先级倒置,引起性能风险。 volatile是不错的机制,但是volatile不能保...

  • Python编程基础 Datawhale Task07:类、对象与魔法方法(3天)

    类与对象 1. 对象 = 属性 + 方法 对象是类的实例。换句话说,类主要定义对象的结构,然后我们以类为模板创建对象。类不但包含方法定义,而且还包含所有实例共享的数据。 封装:信息隐蔽技术 我们可以使用关键字 class 定义 Python 类,关键字后面紧跟类的名称、分号和类的实现。 class Turtle: # Python中的类名约定以大写字母开头 """关于类的一个简单例...

  • C++基础知识(四)-友元和运算符重载

    整理码字不易,养成好习惯,点赞关注,你的支持就是我写下去的动力,谢谢老板。 本文为C++第三篇后续接着这篇文章写,大家可以持续关注,前三篇在主页 4.5 友元 类的主要特点之一是数据隐藏,即类的私有成员无法在类的外部(作用域之外)访问。但是,有时候需要在类的外部访问类的私有成员,怎么办? 解决方法是使用友元函数,友元函数是一种特权函数,c++允许这个特权函数访问私有成员。这一点从现实生活中也...

  • Mybatis 框架下 SQL 注入攻击的 3 种方式,真是防不胜防!

    点击上方“阿拉奇学Java”,选择“置顶或者星标” 每天早晨00点00分,与你相约! 往日回顾:贼好用的Java工具类库,GitHub星标13k+,很是厉害! 前言 SQL注入漏洞作为WEB安全的最常见的漏洞之一,在java中随着预编译与各种ORM框架的使用,注入问题也越来越少。 新手代码审计者往往对Java Web应用的多个框架组合而心生畏惧,不知如何下手,希望通过Mybatis框架使用不...

华为云40多款云服务产品0元试用活动

免费套餐,马上领取!
CSDN

CSDN

中国开发者社区CSDN (Chinese Software Developer Network) 创立于1999年,致力为中国开发者提供知识传播、在线学习、职业发展等全生命周期服务。