热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

JDK中的SA(ServiceAbility)工具介绍

转自https:www.jianshu.comp7c40274441a4最近在网上看到rednaxelafx关于HSDB的介绍,感觉打开了解jvm细节的一扇大门,之

转自https://www.jianshu.com/p/7c40274441a4

最近在网上看到rednaxelafx关于HSDB的介绍,感觉打开了解jvm细节的一扇大门,之前只是纯粹的了解理论, 而现在可以通过该工具去深入查看内部的细节;

概述

SA包含在$JAVA_HOME/lib/sa-jdi.jar中,包括三个工具:
1.CLHSDB:

命令行版本

java -cp .:$JAVA_HOME/lib/sa-jdi.jar sun.jvm.hotspot.CLHSDB

2.HSDB

图形界面版本

java -cp .:$JAVA_HOME/lib/sa-jdi.jar sun.jvm.hotspot.HSDB

3.JSDB:

Javascript引擎版本

java -cp .:$JAVA_HOME/lib/sa-jdi.jar sun.jvm.hotspot.tools.soql.JSDB

用途

SA的一个限制是它只实现了调试snapshot的功能,因此要么要让被调试的目标进程完全暂停,要么就调试core dump;另外注意,SA调试通常要求拥有root权限,否则会报错

调试本地进程

  1. 获取要调试的进程ID:

    ps -ef|grep javajps -mvl
  2. attch进程

    java -cp .:$JAVA_HOME/lib/sa-jdi.jar sun.jvm.hotspot.CLHSDBattach PID

    sudo java -cp .:$JAVA_HOME/lib/sa-jdi.jar sun.jvm.hotspot.HSDB通过菜单"File"->"Attach to HotSpot process",录入PID

调试远程进程

  1. 远程机器上启动rmiregistry服务;

    rmiregistry -J-d64 -J-Xbootclasspath/p:${JAVA_HOME}/lib/sa-jdi.jar                或rmiregistry -J-Xbootclasspath/p:${JAVA_HOME}/lib/sa-jdi.jar
  2. 启动debug server:

客户端通过机器名称连接到debug server进行调试,默认情况下,当只启动一个debug server时,机器名称为ip地址;

 ```bash java -d64 -classpath ${JAVA_HOME}/lib/sa-jdi.jar sun.jvm.hotspot.jdi.SADebugServer  或 java -d64 -classpath ${JAVA_HOME}/lib/sa-jdi.jar sun.jvm.hotspot.jdi.SADebugServer   ```

调试core dump

java -cp .:$JAVA_HOME/lib/sa-jdi.jar sun.jvm.hotspot.CLHSDB $JAVA_HOME/bin/java core-file-name

注意:为了使Java程序能够产生core dump,必须设置ulimit -c unlimited,另外在Linux或Solaris下可以通过kill -6 手工产生core dump。

高级用法

关于使用SA了解JAVA内存布局和解决问题,可以参考如下的文章:

  1. 借HSDB来探索HotSpot VM的运行时数据
  2. 借助HotSpot SA来一窥PermGen上的对象
  3. 怎么查看运行时常量池的数据?
  4. 代码样例

Javascript支持

SA提供了jseval指令,可以执行js代码,其中提供部分内置的js函数和全局变量,具体可以参见sun.jvm.hotspot.utilities.soql.JSJavascriptEngine的216~232行:

高级API

println("Function/Variable Description");        println("================= ===========");        println("address(jobject) returns the address of the Java object");        println("classof(jobject) returns the class object of the Java object");        println("dumpClass(jclass,[dir]) writes .class for the given Java Class");        println("dumpHeap([file]) writes heap in hprof binary format");        println("help() prints this help message");        println("identityHash(jobject) returns the hashCode of the Java object");        println("mirror(jobject) returns a local mirror of the Java object");        println("load([file1, file2,...]) loads Javascript file(s). With no files, reads ");        println("object(string) converts a string address into Java object");        println("owner(jobject) returns the owner thread of this monitor or null");        println("sizeof(jobject) returns the size of Java object in bytes");        println("staticof(jclass, field) returns a static field of the given Java class");        println("read([prompt]) reads a single line from standard input");        println("quit() quits the interactive load call");        println("jvm the target jvm that is being debugged");

底层API

具体的实现代码参见sun.jvm.hotspot.utilities.soql包下面的sa.js,由于代码比较长,此处仅截取部分:

var sapkg = new Object();sapkg.hotspot = Packages.sun.jvm.hotspot;sapkg.asm = sapkg.hotspot.asm;sapkg.bugspot = sapkg.hotspot.bugspot;sapkg.c1 = sapkg.hotspot.c1;sapkg.code = sapkg.hotspot.code;sapkg.compiler = sapkg.hotspot.compiler;// 'debugger' is a Javascript keyword :-(// sapkg.debugger = sapkg.hotspot.debugger;sapkg.interpreter = sapkg.hotspot.interpreter;sapkg.livejvm = sapkg.hotspot.livejvm;sapkg.jdi = sapkg.hotspot.jdi;sapkg.memory = sapkg.hotspot.memory;sapkg.oops = sapkg.hotspot.oops;sapkg.runtime = sapkg.hotspot.runtime;sapkg.tools = sapkg.hotspot.tools;sapkg.types = sapkg.hotspot.types;sapkg.ui = sapkg.hotspot.ui;sapkg.utilities = sapkg.hotspot.utilities;// SA singletons are kept in 'sa' objectvar sa = new Object();sa.vm = sapkg.runtime.VM.getVM();sa.dbg = sa.vm.getDebugger();sa.cdbg = sa.dbg.CDebugger;sa.heap = sa.vm.universe.heap();sa.systemDictiOnary= sa.vm.systemDictionary;sa.sysDict = sa.systemDictionary;sa.symbolTable = sa.vm.symbolTable;sa.symTbl = sa.symbolTable;sa.threads = sa.vm.threads;sa.interpreter = sa.vm.interpreter;sa.typedb = sa.vm.typeDataBase;sa.codeCache = sa.vm.codeCache;// 'objHeap' is different from 'heap'!. // This is SA's Oop factory and heap-walkersa.objHeap = sa.vm.objectHeap;// few useful global variablesvar OS = sa.vm.OS;var CPU = sa.vm.CPU;var LP64 = sa.vm.LP64;var isClient = sa.vm.clientCompiler;var isServer = sa.vm.serverCompiler;var isCore = sa.vm.isCore();var addressSize = sa.vm.addressSize;var oopSize = sa.vm.oopSize;

常用命令

1.查看内建函数和变量

jseval "help()"

jvm全局变量

属性名称 备注
addressSize 32位还是64位
buildInfo jdk构建新型,包括版本号,构建日期,编译器等
cpu CPU类型,例如:x86_64
flags 类似-XX:+PrintFlagsFinal效果
heap  
os 操作系统信息,例如:solaris、linux、bsd、wind32等
sysProps 返回jvm的系统属性,和jinfo命令看到的类似
threads 线程列表
type Client、Server、Core
version JDK版本
classpath java.class.path
bootClasspath sun.boot.class.path
userDir user.dir

查看线程对象属性代码:

jseval "t=jvm.threads[jvm.threads.length-1]"jseval "for(k in t){print(k);print(',');}"

代码样例

jseval "st.stringsDo(function (s) { if (sapkg.oops.OopUtilities.stringOopToString(s).matches('^(a|b).')) {print(s + ': '); s.printValueOn(java.lang.System.out); println('')}})"jseval "java.lang.Long.toHexString(0x0000000193899df0+sapkg.oops.ConstantPool.headerSize*4)"
java -classpath .:$SAPATH/sa-jdi.jar sun.jvm.hotspot.tools.JMap -histo `pgrep java` > jmap_output.log
jstack -m $JAVA_HOME/bin/java core.11028 

jstack有时候看不到具体的错误信息,可以通过开关
export LIBSAPROC_DEBUG=1打开



作者:allanYan
链接:https://www.jianshu.com/p/7c40274441a4
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

推荐阅读
  • centos安装Mysql的方法及步骤详解
    本文介绍了centos安装Mysql的两种方式:rpm方式和绿色方式安装,详细介绍了安装所需的软件包以及安装过程中的注意事项,包括检查是否安装成功的方法。通过本文,读者可以了解到在centos系统上如何正确安装Mysql。 ... [详细]
  • Skywalking系列博客1安装单机版 Skywalking的快速安装方法
    本文介绍了如何快速安装单机版的Skywalking,包括下载、环境需求和端口检查等步骤。同时提供了百度盘下载地址和查询端口是否被占用的命令。 ... [详细]
  • Servlet多用户登录时HttpSession会话信息覆盖问题的解决方案
    本文讨论了在Servlet多用户登录时可能出现的HttpSession会话信息覆盖问题,并提供了解决方案。通过分析JSESSIONID的作用机制和编码方式,我们可以得出每个HttpSession对象都是通过客户端发送的唯一JSESSIONID来识别的,因此无需担心会话信息被覆盖的问题。需要注意的是,本文讨论的是多个客户端级别上的多用户登录,而非同一个浏览器级别上的多用户登录。 ... [详细]
  • 本文详细介绍了在Linux虚拟化部署中进行VLAN配置的方法。首先要确认Linux系统内核是否已经支持VLAN功能,然后配置物理网卡、子网卡和虚拟VLAN网卡的关系。接着介绍了在Linux配置VLAN Trunk的步骤,包括将物理网卡添加到VLAN、检查添加的VLAN虚拟网卡信息以及重启网络服务等。最后,通过验证连通性来确认配置是否成功。 ... [详细]
  • 本文介绍了Linux系统中正则表达式的基础知识,包括正则表达式的简介、字符分类、普通字符和元字符的区别,以及在学习过程中需要注意的事项。同时提醒读者要注意正则表达式与通配符的区别,并给出了使用正则表达式时的一些建议。本文适合初学者了解Linux系统中的正则表达式,并提供了学习的参考资料。 ... [详细]
  • 记录一次es集群load过高问题(待更新)
    toptop-H-ppid按shiftp以cpu来排序按shiftm以memory来排序将10进制线程pid转为16进制printf%x\npidjstackjstackP ... [详细]
  • 如何在服务器主机上实现文件共享的方法和工具
    本文介绍了在服务器主机上实现文件共享的方法和工具,包括Linux主机和Windows主机的文件传输方式,Web运维和FTP/SFTP客户端运维两种方式,以及使用WinSCP工具将文件上传至Linux云服务器的操作方法。此外,还介绍了在迁移过程中需要安装迁移Agent并输入目的端服务器所在华为云的AK/SK,以及主机迁移服务会收集的源端服务器信息。 ... [详细]
  • Linux如何安装Mongodb的详细步骤和注意事项
    本文介绍了Linux如何安装Mongodb的详细步骤和注意事项,同时介绍了Mongodb的特点和优势。Mongodb是一个开源的数据库,适用于各种规模的企业和各类应用程序。它具有灵活的数据模式和高性能的数据读写操作,能够提高企业的敏捷性和可扩展性。文章还提供了Mongodb的下载安装包地址。 ... [详细]
  • 【shell】网络处理:判断IP是否在网段、两个ip是否同网段、IP地址范围、网段包含关系
    本文介绍了使用shell脚本判断IP是否在同一网段、判断IP地址是否在某个范围内、计算IP地址范围、判断网段之间的包含关系的方法和原理。通过对IP和掩码进行与计算,可以判断两个IP是否在同一网段。同时,还提供了一段用于验证IP地址的正则表达式和判断特殊IP地址的方法。 ... [详细]
  • 一次上线事故,30岁+的程序员踩坑经验之谈
    本文主要介绍了一位30岁+的程序员在一次上线事故中踩坑的经验之谈。文章提到了在双十一活动期间,作为一个在线医疗项目,他们进行了优惠折扣活动的升级改造。然而,在上线前的最后一天,由于大量数据请求,导致部分接口出现问题。作者通过部署两台opentsdb来解决问题,但读数据的opentsdb仍然经常假死。作者只能查询最近24小时的数据。这次事故给他带来了很多教训和经验。 ... [详细]
  • Python基础知识:注释、输出和input交互
    本文介绍了Python基础知识,包括注释的使用、输出函数print的用法以及input函数的交互功能。其中涉及到字符串和整数的类型转换等内容。 ... [详细]
  • 负载均衡_Nginx反向代理动静分离负载均衡及rewrite隐藏路径详解(Nginx Apache MySQL Redis)–第二部分
    nginx反向代理、动静分离、负载均衡及rewrite隐藏路径详解 ... [详细]
  • 第四讲ApacheLAMP服务器基本配置Apache的编译安装从Apache的官方网站下载源码包:http:httpd.apache.orgdownload.cgi今 ... [详细]
  • 我创建了一个新的AWSSSO(使用内部IDP作为身份源,因此不使用ActiveDirectory)。我能够登录AWSCLI、AWSGUI,但 ... [详细]
  • 生产环境下JVM调优参数的设置实例
     正文前先来一波福利推荐: 福利一:百万年薪架构师视频,该视频可以学到很多东西,是本人花钱买的VIP课程,学习消化了一年,为了支持一下女朋友公众号也方便大家学习,共享给大家。福利二 ... [详细]
author-avatar
手浪用户2602886151
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有