JDK 命令行工具

JDK 命令行工具1


前言

  1. 教程资料
    1. Java自带的性能监测工具
    2. JVM虚拟机
  2. 反思问题
    1. 为何 java -Xms32m -Xmx32m 设置堆空间大小后,通过命令 jinfo -flag MaxHeapSize pid 查询到结果 478150656/1024/1024 = 456m 而不是32m
      1. java -xms 是设置JDK运行环境的堆空间配置
      2. 项目应用是部署在 Tomcat 应用服务器中,Tomcat 是通过 JVM 启动,他们的脚本中可以独立配置 JVM 运行时环境的参数
      3. jinfo -flag MaxHeapSize pid 查询的结果是 java -XX:+PrintFinalFlags 中设置的最终 MaxHeapSize
      4. IDEA 运行时JVM环境修改:${IDEA}/bin/idea64.exe.vmoptions
      5. Eclipse 运行时JVM环境修改:eclipse.ini
      6. Linux 中 Tomcat 的JVM环境修改:cd ${tomcat}/bin --> vi catalina.sh --> 添加如下代码
        # OS specific support. $var _must_ be set to either true or false. # OS specific support. $var _must_ be set to either true or false. JAVA_OPTS="-Xms256m -Xmx512m -Xss1024K -XX:PermSize=128m -XX:MaxPermSize=256m" cygwin=false

一、命令行工具2

命令 全称 用途
jps JVM Process Status Tool 显示指定系统内所有的HotSpot虚拟机进程
jinfo Configuration Info for Java 显示虚拟机配置信息
jstat JVM Statistics Monitoring Tool 用于收集Hotspot虚拟机各方面的运行数据
jmap JVM Memory Map 生成虚拟机的内存转储快照,生成heapdump文件
jhat JVM Heap Dump Browser 用于分析heapdump文件,它会建立一个HTTP/HTML服务器,让用户在浏览器上查看分析结果
jstack JVM Stack Trace 显示虚拟机的线程快照

二、基础知识

  1. JVM 类型
    1. 选择依据: 根据硬件及操作系统自动选择
    2. JVM命令:
      1. -server :选择JVM类型,Server VM,默认类型
      2. -client:选择JVM类型,Client VM
    3. 主要区别:
类型名称 初始化堆空间大小 垃圾回收器 机器位数 备注信息
Server VM 大一些 并行 64-bit -
Client VM 小一些 串行 32-bit 在 64-bit 机器上无法切换到 Client VM 类型
  1. JIT3 即时编译模式

    1. 代码解释与即时编译
      JDK 命令行工具_第1张图片
    2. JVM 命令
      1. -Xint : 解释执行,即关闭JIT即时编译,速度会很慢
      2. -Xcomp : 所有字节码首先被编译为本地字节码再执行,速度会很快,但很耗性能,因为存在只运行一次的代码,这样的代码进行编译效果不明显
      3. -Xmixed:混合模式,JVM自己来决定何时转为本地代码,HotSpot VM 默认的编译模式
  2. JVM 内存结构 JDK 1.8

一级 二级 三级
堆区 年轻代
survival 0
survival 1
Eden
老年代
非堆区 Metaspace
CCS
CodeCache
  1. JVM 内存结构 JDK 1.7
一级 二级 三级
堆区 年轻代
survival 0
survival 1
Eden
老年代
持久代 方法区
其他

三、JVM 参数类型4

  1. 标准参数:功能稳定
    1. -help:查看所有标准选项
  2. 非标准参数:不同版本JVM功能略有不同
    1. X参数:以-X开头
      1. java -X 查看所有 -X 配置参数
    2. XX参数:主要是给JVM开发者用于开发和调试JVM的
      1. Boolean
        1. 格式:-XX:[±]表示开启或者禁用name属性
        2. 比如:-XX:+UseG1GC,打开G1GC功能
      2. 非Boolean
        1. 格式:-XX:= name的属性值是value
        2. 比如:
          -XX:InitialHeapSize 初始化堆大小 = -Xms
          -XX:MaxHeapSize 设置最大堆大小 = -Xmx
          -XX:ThreadStackSize 堆栈大小 = -Xss
          -XX:PermSize 用来设置永久区的初始大小
          -XX:MaxPermSize 用来设置永久区的最大值

四、JAVA5

  1. java -version:

    1. 查看信息
      1. JDK 版本
      2. JAVA 版本
      3. JVM 类型
      4. JIT 即时编译模式
    2. 命令解析
      java -version运行结果
      1. Java(TM):TM 是 TradeMark 的简写,商标注册,无实际含义6
      2. SE :Java Platform,Standard Edition ,Java 版本
      3. Runtime Environment: 运行时环境信息
      4. HotSpot7:目前使用范围最广的Java虚拟机,Hot Spot 热点,默认使用 JIT 即时编译模式,对热点代码进行特殊处理
      5. Server VM:JVM 类型
      6. mixed mode : JIT 模式
  2. java -Xms :是指程序启动时初始内存大小(此值可以设置成与-Xmx相同,以避免每次GC完成后 JVM 内存重新分配)

  3. java -Xmx:指程序运行时最大可用内存大小,程序运行中内存大于这个值会 OutOfMemory

  4. java -Xss :设置每个线程的堆栈大小

  5. java -XX:+UseConcMarkSweepGC 并发标记清除(CMS)收集器8

  6. java -XX:+UnlockExperimentalVMOptions 解锁实验参数

  7. java -XX:+UnlockDiagnosticVMOptions 解锁诊断参数

  8. java -XX:+PrintCommandLineFlags 用户手动设置或者JVM自动设置的XX选项

  9. java -XX:+PrintFlagsInitial 打印出所有XX选项的默认值

  10. java -XX:+PrintFlagsFinal 打印出XX选项在运行程序时生效的值

    1. java -XX:PrintFlagsFinal -version > a.txt 便于查看将查询结果输出到文档中
    2. cat a.txt 查看文件内容
    3. = 与 := 区别
      1. = 表示默认值
      2. := 被用户或者JVM修改后的值

JDK 命令行工具_第2张图片

  1. -XX:+HeapDumpOnOutOfMemoryError 当发生内存溢出时将文件dump出来
  2. -XX:HeapDumpPath=./ 发生内存溢出时自动检出映像文件的存放位置

五、JPS9

  1. 全称:Java Virtual Machine Process Status Tool
  2. 版本:JDK 1.5 以后
  3. 功能:显示当前Java所有相关进程PID,不同于 ps -ef 打印所有 Linux 进程信息
    1. 查看进程编号
      1. jps 部署一个应用
      2. ps -ef | grep “application-name” 部署多个应用
  4. 作用:检查是否有Java进程在启动
  5. 参数:
    1. -v 打印PID及JVM 参数配置
    2. -l 打印PID及类全名
    3. -m 打印PID及主函数传入的参数
  6. 官方文档10
  7. JPS -V 解析
    JPS
PID CLASS 含义
18913 Bootstrap org.apache.catalina.startup.Bootstrap
-Djava.util.logging.config.file=/root/apache-tomcat-8.5.37/conf/logging.properties
-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager
-Djdk.tls.ephemeralDHKeySize=2048
-Djava.protocol.handler.pkgs=org.apache.catalina.webresources
-Dorg.apache.catalina.security.SecurityListener.UMASK=0027
-Dignore.endorsed.dirs= -Dcatalina.base=/root/apache-tomcat-8.5.37
-Dcatalina.home=/root/apache-tomcat-8.5.37
-Djava.io.tmpdir=/root/apache-tomcat-8.5.37/temp
19231 Jps sun.tools.jps.Jps
-Denv.class.path=.:/usr/lib/jvm/java/lib/dt.jar:/usr/lib/jvm/java/lib/tools.jar:/usr/lib/jvm/java/jre/lib/rt.jar
-Dapplication.home=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.191.b12-1.el7_6.x86_64 -Xms8m

六、Jinfo11

  1. 全称:Java Virtual Machine Information Tool
  2. 功能:查看正在运行的java运用程序的扩展参数,支持在运行时动态地更改部分参数
  3. 语法:
    1. jinfo - 基本命令格式
    2. -flag : 打印指定java虚拟机的参数值
    3. -flag [+|-] :设置或取消指定java虚拟机参数的布尔值
    4. -flag = : 设置指定java虚拟机的参数的值
  4. 命令:
    1. 参数查询
      1. jinfo -flag MaxHeapSize pid 查看JVM堆栈信息配置最大值
        1. -XX:MaxHeapSize=478150656
        2. 输出结果单位为bit ,转为 M ,xx bit / 1024 /1024 = xx M
        3. java -Xms1024m 设置单位不同,此处为 m 或 g
      2. jinfo -flag MaxTenuringThreshold pid 查看JVM新生代对象晋升到老年代对象的最大年龄
      3. jinfo -flag PrintGCDetails pid 查看显示是否打印gc详细信息
      4. jinfo -flags pid 查看JVM配置默认值
      5. jinfo -flag UseConcMarkSweepGC pid
      6. jinfo -flag UseG1GC pid
      7. jinfo -flag UseParallelGC pid 查看并行垃圾回收器开关
      8. flag 后的参数可通过 java -XX:+PrintFlagsFinal > a.txt 获取
    2. 设置开关
      1. jinfo -flag +PrintGCDetails pid 打开JVM中GC信息开关
      2. jinfo -flag -PrintGCDetails pid 关闭JVM中GC信息开关

七、Jstat 12

  1. 功能:jstat命令可以查看堆内存各部分的使用量,以及加载类的数量
  2. 语法:jstat [-命令选项] [vmid] [间隔时间/毫秒] [查询次数]
  3. 命令
项目含义 对应命令
类加载统计 -class
编译统计 -compiler
垃圾回收统计 -gc
堆内存统计 -gccapacity
新生代垃圾回收统计 -gcnew
新生代内存统计 -gcnewcapacity
老年代垃圾回收统计 -gcold
老年代内存统计 -gcoldcapacity
元数据空间统计 -gcmetacapacity
总结垃圾回收统计 -gcutil
JVM 编译方法统计 -printcompilation
  1. 类加载统计
[root@linux01 ~]# jstat -class 16971 10 10
Loaded  Bytes  Unloaded  Bytes     Time   
  4963  9887.1        0     0.0       6.53
  4963  9887.1        0     0.0       6.53
  4963  9887.1        0     0.0       6.53
  4963  9887.1        0     0.0       6.53
  4963  9887.1        0     0.0       6.53
  4963  9887.1        0     0.0       6.53
  4963  9887.1        0     0.0       6.53
  4963  9887.1        0     0.0       6.53
  4963  9887.1        0     0.0       6.53
  4963  9887.1        0     0.0       6.53
名称 含义
Loaded 加载class的数量
Bytes 所占用空间大小
Unloaded 未加载数量
Bytes 未加载占用空间
Time 时间
  1. 编译统计
[root@linux01 ~]# jstat -compiler 16971 10 10 
Compiled Failed Invalid   Time   FailedType FailedMethod
    2990      0       0     8.86          0             
    2990      0       0     8.86          0             
    2990      0       0     8.86          0             
    2990      0       0     8.86          0             
    2990      0       0     8.86          0             
    2990      0       0     8.86          0             
    2990      0       0     8.86          0             
    2990      0       0     8.86          0             
    2990      0       0     8.86          0             
    2990      0       0     8.86          0 
名称 含义
Loaded 加载class的数量
Compiled 编译数量。
Failed 失败数量
Invalid 不可用数量
Time 时间
FailedType 失败类型
FailedMethod 失败的方法
  1. 垃圾回收统计
[root@linux01 ~]# jstat -gc 16971 10 10 
 S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT   
1344.0 1344.0  2.0    0.0   11136.0   655.4    27580.0    18048.6   30336.0 29551.2 3456.0 3307.3     86    0.281   2      0.077    0.358
1344.0 1344.0  2.0    0.0   11136.0   655.4    27580.0    18048.6   30336.0 29551.2 3456.0 3307.3     86    0.281   2      0.077    0.358
1344.0 1344.0  2.0    0.0   11136.0   655.4    27580.0    18048.6   30336.0 29551.2 3456.0 3307.3     86    0.281   2      0.077    0.358
1344.0 1344.0  2.0    0.0   11136.0   655.4    27580.0    18048.6   30336.0 29551.2 3456.0 3307.3     86    0.281   2      0.077    0.358
1344.0 1344.0  2.0    0.0   11136.0   655.4    27580.0    18048.6   30336.0 29551.2 3456.0 3307.3     86    0.281   2      0.077    0.358
1344.0 1344.0  2.0    0.0   11136.0   655.4    27580.0    18048.6   30336.0 29551.2 3456.0 3307.3     86    0.281   2      0.077    0.358
1344.0 1344.0  2.0    0.0   11136.0   655.4    27580.0    18048.6   30336.0 29551.2 3456.0 3307.3     86    0.281   2      0.077    0.358
1344.0 1344.0  2.0    0.0   11136.0   655.4    27580.0    18048.6   30336.0 29551.2 3456.0 3307.3     86    0.281   2      0.077    0.358
1344.0 1344.0  2.0    0.0   11136.0   655.4    27580.0    18048.6   30336.0 29551.2 3456.0 3307.3     86    0.281   2      0.077    0.358
1344.0 1344.0  2.0    0.0   11136.0   655.4    27580.0    18048.6   30336.0 29551.2 3456.0 3307.3     86    0.281   2      0.077    0.358

名称 含义
S0C 第一个幸存区的大小
S1C 第二个幸存区的大小
S0U 第一个幸存区的使用大小
S1U 第二个幸存区的使用大小
EC 伊甸园区的大小
EU 伊甸园区的使用大小
OC 老年代大小
OU 老年代使用大小
MC 方法区大小
MU 方法区使用大小
CCSC 压缩类空间大小
CCSU 压缩类空间使用大小
YGC 年轻代垃圾回收次数
YGCT 年轻代垃圾回收消耗时间
FGC 老年代垃圾回收次数
FGCT 老年代垃圾回收消耗时间
GCT 垃圾回收消耗总时间
  1. 含义解释
    1. C :Capacity
    2. U :Used

八、Jmap

  1. 功能:打印出某个java进程(使用pid)内存内的,所有‘对象’的情况(如:产生那些对象,及其数量)13
  2. 用途:为了展示java进程的内存映射信息,或者堆内存详情用途是为了展示java进程的内存映射信息,或者堆内存详情
  3. 命令:jmap -dump:format=b,file=filename pid
  4. 模拟:内存溢出
    1. 搭建Demo项目
      1. eclipse + SpringBoot
        1. https://start.spring.io/
        2. 生成 Spring Boot 项目
        3. dependencies 选择 web
        4. 下载、解压到本地文件夹、导入 Eclipse 中
        5. 使用此种方式运行时方便修改 JVM 参数
      2. idea + SpringMVC + Tomcat + Linux
        1. 搭建 SpringMVC 项目14
        2. 使用此种方式的原因是太久没有用eclipse,本机没有安装
    2. 编写 DEMO 示例
      1. 运行时动态生产 class 文件的方式
        1. JDK 中的代理API
        2. Cglib
        3. ASM15
package com.ssm.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

/**
 * 模拟内存溢出场景
 * @author study
 */
@Controller
@RequestMapping("/memory")
public class MemoryController {

    private List userList = new ArrayList();

    /**
     * 模拟堆溢出异常
     * JVM 运行环境设置 -Xmx 32M  -Xms 32M
     */
    @RequestMapping("/heap")
    public void heap(){
        int index = 0 ;
        while (true){
            userList.add(new User(index++, UUID.randomUUID().toString()));
        }
    }

    /**
     * 用户信息实体类
     */
    public class User{

        public User(Integer id ,String name){
            this.id = id ;
            this.name = name ;
        }

        /**
         * 用户编号
         */
        private Integer id ;
        /**
         * 用户姓名
         */
        private String name ;

        public Integer getId() {
            return id;
        }

        public void setId(Integer id) {
            this.id = id;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }
    }

    private List classList = new ArrayList();

    /**
     * 模拟方法区溢出异常
     * JVM 运行环境设置 -XX:MetaspaceSize=32M --XX:MaxMetaspaceSize=32M
     * JDK 1.8
     */
    @RequestMapping("/method")
    public void method(){
        // 通过 ASM 动态生成 Class 文件,存入 classList 中
    }
}

  1. 部署:将项目部署到Linux中
    1. 原因:
      1. IDEA 无法动态配置JVM运行时参数
      2. IDEA 无法配置 -XX:+HeapDumpOnOutOfMemoryError 当发生内存溢出时将文件dump出来 -XX:HeapDumpPath=./
    2. 操作
      1. 项目导出 war 包
        1. 命令: IDEA --> Maven --> Package -->
        2. 拷贝:Run 窗口输出 Building war: {path}\SpringMVC\target\SpringMVC.war
      2. 部署运行 war 包
        1. 删除 tomcat/webapps/ROOT 目录下所有文件
        2. 拷贝 war 包到 tomcat/webapps/ROOT
        3. 运行 jar -xvf SpringMVC.war
          1. -v 在标准输出中生成详细输出
          2. -f 指定档案文件名
        4. 启动 tomcat 服务
          1. cd …/tomcat/bin
          2. ./shutdown.sh 关闭进程
          3. ./start.sh 启动进程
          4. JPS 查看启动进程编号
  2. 配置自动检出内存映像文件
    1. 虚拟机设置自动 dump 内存映像
    2. 内存映像默认存放位置 tomcat/bin 目录下
	[root@linux01 bin]# jinfo -flag HeapDumpOnOutOfMemoryError 16964
	-XX:-HeapDumpOnOutOfMemoryError
	[root@linux01 bin]# jinfo -flag +HeapDumpOnOutOfMemoryError 16964
	[root@linux01 bin]# jinfo -flag HeapDumpOnOutOfMemoryError 16964
	-XX:+HeapDumpOnOutOfMemoryError
	[root@linux01 bin]# jinfo -flag HeapDumpPath=./ 16964
	[root@linux01 bin]# jinfo -flag HeapDumpPath 16964
	-XX:HeapDumpPath=./

JDK 命令行工具_第3张图片

  1. 运行:

    1. 修改 JVM 环境配置:修改 tomcat/bin/catalina.sh 文件添加 JAVA_OPTS

    2. 访问 http://192.168.255.100:8080/memory/heap

    3. 运行结果
      JDK 命令行工具_第4张图片

    4. 执行 jmap -dump:format=b,file=managed_heapdump.hprof pid

      1. format 文件格式
      2. b 二进制
      3. dump 检出映像文件
      4. file 文件名称
    5. 内存溢出时自动检出文件配置

      1. -XX:+HeapDumpOnOutOfMemoryError 当发生内存溢出时将文件dump出来
      2. -XX:HeapDumpPath=./ 检出文件的存放目录
    6. 将映像文件从服务中导出到 Windows 环境

  2. 分析:使用 mat (Memory Analyzer Tool)工具分析内存映像文件

    1. 工具下载
      1. JDK 1.7:https://www.eclipse.org/mat/previousReleases.php
      2. JDK 1.8:http://www.eclipse.org/mat/downloads.php
    2. 导入文件:启动 mat 工具并导入映像文件
    3. 问题分析:
      JDK 命令行工具_第5张图片JDK 命令行工具_第6张图片JDK 命令行工具_第7张图片
  3. 总结: 生产环境分析内存溢出更加复杂,要逐个对象查看强引用对象的引用,逐步定位问题

  4. MAT 使用方法16 17 18

    1. 环境配置
      1. 分析一个堆转储文件需要消耗很多的堆空间,分配给 MAT 尽可能多的内存资源
      2. 编辑文件 MemoryAnalyzer.ini,在里面添加 -vmargs– Xmx4g
      3. 出现加载内存映像文件失败的情况多半是内存空间不足导致的
  5. jmap -histo pid 展示class的内存情况

  6. jmap -finalizerinfo pid 打印等待回收的对象信息

  7. jmap -heap pid 打印堆信息

  8. 堆转储文件实现方式

    1. JConsole
    2. JMap
    3. -XX:+HeapDumpOnCtrlBreak

九、Jhat19 20

  1. 功能:解析Java堆转储文件,并启动一个 web server. 然后用浏览器来查看/浏览 dump 出来的 heap
  2. 命令:jhat -J-Xmx8192m file.hprof
    1. -J 参数是因为默认JVM的堆内存可能不足以加载整个dump 文件. 根据需要进行调整
    2. 运行结果
      JDK 命令行工具_第8张图片
    3. http://localhost:7000/ 访问查询运行结果
      JDK 命令行工具_第9张图片JDK 命令行工具_第10张图片

十、Jstack

  1. 功能:用于生成java虚拟机当前时刻的线程快照
  2. 作用:查看线程执行方法的堆栈信息,定位异常线程问题原因,在等待何种资源,在进行何种操作
  3. 命令:jstack [option] pid
    1. -l 长列表. 打印关于锁的附加信息
    2. -m 打印java和native c/c++框架的所有栈信息. -h | -help打印帮助信息
    3. -F 当’jstack [-l] pid’没有响应的时候强制打印栈信息
  4. 查看堆栈信息步骤
    1. JPS 或 ps -ef | grep “application-name” 查看进程编号
    2. top -Hp pid 查看进程所属线程编号
      1. -H: 显示进程所属所有线程
      2. -p: 监控特定的PID
      3. man top :查看所有相关命令
    3. printf “%x\n” tid 打印线程编号对应十六进制数值
      1. %x 十六进制
      2. %o 八进制
      3. %d 十进制
      4. \n 换行,方便复制结果
    4. jstack -l | grep “{%x}” -A n 查看线程对应堆栈信息
      1. -A是显示匹配后和它后面的n行。
      2. -B是显示匹配行和它前面的n行。
      3. -C是匹配行和它前后各n行。
  5. 项目示例 synchronized21
package com.ssm.controller;

import com.ssm.biz.thread.Blocked;
import com.ssm.biz.thread.DeadLock;
import javafx.concurrent.Task;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 模拟线程异常场景
 * @author study
 */
@Controller
@RequestMapping("/thread")
public class ThreadController {

    /**
     * 模拟死锁场景
     * @return  跳转首页
     */
    @RequestMapping("/deadLock")
    public String deadLock(){

        Thread thread1 = new Thread(new DeadLock(),"thread-1");
        Thread thread2 = new Thread(new DeadLock(),"thread-2");
        thread1.start();
        thread2.start();
        return "index";
    }

    private ExecutorService es = Executors.newFixedThreadPool(5);

    /**
     * 模拟资源竞争
     * @return  跳转首页
     */
    @RequestMapping("blocked")
    public String blocked(){

        Blocked b1 = new Blocked();
        Blocked b2 = new Blocked();
        es.execute(b1);
        es.execute(b2);
        return "index";
    }
}

package com.ssm.biz.thread;

/**
 * @author study
 * 模拟死锁
 */
public class DeadLock implements Runnable{

    private static Object lock1 = new Object();
    private static Object lock2 = new Object();
    private static boolean flag ;

    public void run() {
        System.out.println(Thread.currentThread().getName()+" running");
        if(flag){
            synchronized (lock1){
                System.out.println(Thread.currentThread().getName()+" acquire lock1");
                try {
                    Thread.sleep(1000L);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (lock2){
                    System.out.println(Thread.currentThread().getName()+" acquire lock2");
                }
            }
        }else{
            synchronized (lock2){
                System.out.println(Thread.currentThread().getName()+" acquire lock2");
                try {
                    Thread.sleep(1000L);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (lock1){
                    System.out.println(Thread.currentThread().getName()+" acquire lock1");
                }
            }
        }
    }
}

package com.ssm.biz.thread;

/**
 * @author study
 */
public class Blocked implements Runnable{

    private static Object lock = new Object();

    public void run() {

        synchronized (lock){

            Integer index = 0 ;
            while (true){
                index++;
            }

        }
    }
}

  1. 操作示例
    1. 执行命令 top -Hp 18824
    2. 请求链接 http://192.168.255.100:8080/thread/synchronizedLock
    3. 观察线程占用CPU的变化
[root@linux01 bin]# top -Hp 18824
Threads:  43 total,   0 running,  43 sleeping,   0 stopped,   0 zombie
%Cpu(s): 10.0 us,  0.7 sy,  0.0 ni, 89.2 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :  1863224 total,   488064 free,   288600 used,  1086560 buff/cache
KiB Swap:  2097148 total,  2097148 free,        0 used.  1347608 avail Mem 

   PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND                                                                                                                                                                 
 18830 root      20   0 2549200 145280  16128 S  6.6  7.8   0:09.08 java                                                                                                                                                                    
 18858 root      20   0 2549200 145280  16128 S  4.7  7.8   0:00.18 java                                                                                                                                                                    
 18851 root      20   0 2549200 145280  16128 S  3.0  7.8   0:00.39 java                                                                                                                                                                    
 18831 root      20   0 2549200 145280  16128 S  1.7  7.8   0:02.64 java                                                                                                                                                                    
 18842 root      20   0 2549200 145280  16128 S  0.3  7.8   0:00.37 java                                                                                                                                                                    
 18824 root      20   0 2549200 145280  16128 S  0.0  7.8   0:00.00 java                                                                                                                                                                    
 18825 root      20   0 2549200 145280  16128 S  0.0  7.8   0:01.63 java                                                                                                                                                                    
 18826 root      20   0 2549200 145280  16128 S  0.0  7.8   0:01.27 java                                                                                                                                                                    
 18827 root      20   0 2549200 145280  16128 S  0.0  7.8   0:00.00 java                                                                                                                                                                    
 18828 root      20   0 2549200 145280  16128 S  0.0  7.8   0:00.01 java                                                                                                                                                                    
 18829 root      20   0 2549200 145280  16128 S  0.0  7.8   0:00.00 java                                                                                                                                                                    
 18832 root      20   0 2549200 145280  16128 S  0.0  7.8   0:00.00 java                                                                                                                                                                    
 18833 root      20   0 2549200 145280  16128 S  0.0  7.8   0:15.71 java                                                                                                                                                                    
 18834 root      20   0 2549200 145280  16128 S  0.0  7.8   0:00.46 java                                                                                                                                                                    
 18837 root      20   0 2549200 145280  16128 S  0.0  7.8   0:00.00 java                                                                                                                                                                    
 18841 root      20   0 2549200 145280  16128 S  0.0  7.8   0:00.32 java                                                                                                                                                                    
 18850 root      20   0 2549200 145280  16128 S  0.0  7.8   0:01.81 java                                                                                                                                                                    
 18852 root      20   0 2549200 145280  16128 S  0.0  7.8   0:00.00 java                                                                                                                                                                    
 18853 root      20   0 2549200 145280  16128 S  0.0  7.8   0:00.00 java                                                                                                                                                                    
 18854 root      20   0 2549200 145280  16128 S  0.0  7.8   0:00.00 java                                                                                                                                                                    
 18855 root      20   0 2549200 145280  16128 S  0.0  7.8   0:00.00 java                                                                                                                                                                    
 18856 root      20   0 2549200 145280  16128 S  0.0  7.8   0:00.00 java                                                                                                                                                                    
 18857 root      20   0 2549200 145280  16128 S  0.0  7.8   0:00.00 java                                                                                                                                                                    
 18859 root      20   0 2549200 145280  16128 S  0.0  7.8   0:00.01 java                                                                                                                                                                    
 18860 root      20   0 2549200 145280  16128 S  0.0  7.8   0:00.00 java                                                                                                                                                                    
 18862 root      20   0 2549200 145280  16128 S  0.0  7.8   0:00.44 java                                                                                                                                                                    
 18863 root      20   0 2549200 145280  16128 S  0.0  7.8   0:00.04 java                                                                                                                                                                    
 18864 root      20   0 2549200 145280  16128 S  0.0  7.8   0:00.42 java                                                                                                                                                                    
 18865 root      20   0 2549200 145280  16128 S  0.0  7.8   0:00.00 java                                                                                                                                                                    
 18866 root      20   0 2549200 145280  16128 S  0.0  7.8   0:00.00 java                                                                                                                                                                    
 18867 root      20   0 2549200 145280  16128 S  0.0  7.8   0:00.00 java                                                                                                                                                                    
 18868 root      20   0 2549200 145280  16128 S  0.0  7.8   0:00.00 java                                                                                                                                                                    
 18869 root      20   0 2549200 145280  16128 S  0.0  7.8   0:00.00 java                                                                                                                                                                    
 18870 root      20   0 2549200 145280  16128 S  0.0  7.8   0:00.00 java                                                                                                                                                                    
 18871 root      20   0 2549200 145280  16128 S  0.0  7.8   0:00.00 java                                                                                                                                                                    
 18872 root      20   0 2549200 145280  16128 S  0.0  7.8   0:00.01 java                                                                                                                                                                    
 18873 root      20   0 2549200 145280  16128 S  0.0  7.8   0:00.02 java                                                                                                                                                                    
 18874 root      20   0 2549200 145280  16128 S  0.0  7.8   0:00.00 java                                                                                                                                                                    
 18875 root      20   0 2549200 145280  16128 S  0.0  7.8   0:00.48 java                                                                                                                                                                    
 18876 root      20   0 2549200 145280  16128 S  0.0  7.8   0:00.00 java                                                                                                                                                                    
 18877 root      20   0 2549200 145280  16128 S  0.0  7.8   0:00.58 java                                                                                                                                                                    
 18911 root      20   0 2549200 145280  16128 S  0.0  7.8   0:00.00 java                                                                                                                                                                    
 19269 root      20   0 2549200 145280  16128 S  0.0  7.8   0:00.00 java                                                                                                                                                                    

 
[root@linux01 ~]# printf "%x" 18830 
498e[root@linux01 ~]# jstack 18824 | grep "498e" -A 20 
"C2 CompilerThread0" #5 daemon prio=9 os_prio=0 tid=0x00007f93f0113000 nid=0x498e waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Signal Dispatcher" #4 daemon prio=9 os_prio=0 tid=0x00007f93f0106000 nid=0x498d runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Finalizer" #3 daemon prio=8 os_prio=0 tid=0x00007f93f00da800 nid=0x498c in Object.wait() [0x00007f93e042d000]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x00000000ed1799f0> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:144)
        - locked <0x00000000ed1799f0> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:165)
        at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:216)

"Reference Handler" #2 daemon prio=10 os_prio=0 tid=0x00007f93f00d6000 nid=0x498b in Object.wait() [0x00007f93e052e000]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x00000000ed179ba8> (a java.lang.ref.Reference$Lock)
        at java.lang.Object.wait(Object.java:502)
        at java.lang.ref.Reference.tryHandlePending(Reference.java:191)
		
[root@linux01 ~]# printf "%x" 18858 
49aa[root@linux01 ~]# jstack 18824 | grep "49aa" -A 20 
"http-nio-8080-exec-8" #24 daemon prio=5 os_prio=0 tid=0x00007f93f039f800 nid=0x49aa waiting on condition [0x00007f93bd921000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000000ee224328> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
        at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
        at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:103)
        at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:31)
        at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Thread.java:748)

"http-nio-8080-exec-7" #23 daemon prio=5 os_prio=0 tid=0x00007f93f039c800 nid=0x49a9 waiting on condition [0x00007f93bda22000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000000ee224328> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
		

[root@linux01 ~]# printf "%x\n" 18851 
49a3
[root@linux01 ~]# jstack 18824 | grep "49a3" -A 20 
"http-nio-8080-exec-1" #17 daemon prio=5 os_prio=0 tid=0x00007f93f0424000 nid=0x49a3 waiting on condition [0x00007f93be028000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000000ee224328> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
        at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
        at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:103)
        at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:31)
        at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Thread.java:748)

"ContainerBackgroundProcessor[StandardEngine[Catalina]]" #16 daemon prio=5 os_prio=0 tid=0x00007f93f01ad000 nid=0x49a2 waiting on condition [0x00007f93be342000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
        at java.lang.Thread.sleep(Native Method)
        at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1359)
        at java.lang.Thread.run(Thread.java:748)		

 		
		
[root@linux01 ~]# printf "%x" 18831
498f[root@linux01 ~]# jstack 18824 | grep "498f" -A 20 

"C1 CompilerThread1" #6 daemon prio=9 os_prio=0 tid=0x00007f93f0115000 nid=0x498f waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread0" #5 daemon prio=9 os_prio=0 tid=0x00007f93f0113000 nid=0x498e waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Signal Dispatcher" #4 daemon prio=9 os_prio=0 tid=0x00007f93f0106000 nid=0x498d runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Finalizer" #3 daemon prio=8 os_prio=0 tid=0x00007f93f00da800 nid=0x498c in Object.wait() [0x00007f93e042d000]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x00000000ed1799f0> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:144)
        - locked <0x00000000ed1799f0> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:165)
        at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:216)

"Reference Handler" #2 daemon prio=10 os_prio=0 tid=0x00007f93f00d6000 nid=0x498b in Object.wait() [0x00007f93e052e000]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)


  1. 堆栈信息,导出堆栈信息 jstack pid > a.txt

    1. “” 线程名称,多线程开发时尽量给线程命名,查询堆栈信息时便于定位问题

    2. # 堆栈深度

    3. daemon 系统守护线程,查询堆栈信息时主要查看用户线程,非守护线程

    4. prio JVM 线程优先级

    5. os_prio OS,Operation System 本地操作系统中线程优先级

      1. Linux 三种线程调度策略22
        1. SCHED_OTHER 分时调度策略
        2. SCHED_FIFO 实时调度策略,先到先服务。一旦占用cpu则一直运行。一直运行直到有更高优先级任务到达或自己放弃
        3. SCHED_RR实 时调度策略,时间片轮转。当进程的时间片用完,系统将重新分配时间片,并置于就绪队列尾。放在队列尾保证了所有具有相同优先级的RR任务的调度公平
        4. SCHED_OTHER 是不支持优先级使用的,而 SCHED_FIFO 和 SCHED_RR 支持优先级的使用,他们分别为1和99,数值越大优先级越高
    6. tid JVM 线程编号

    7. nid native 本地操作系统线程编号

    8. []

    9. java.lang.Thread.State

    10. java 线程堆栈信息

  2. 线程示例23

    1. wait
[root@linux01 ~]# jstack 19466 | grep "BLOCKED" -C 20
2019-02-21 02:52:19
Full thread dump OpenJDK 64-Bit Server VM (25.191-b12 mixed mode):

"Attach Listener" #46 daemon prio=9 os_prio=0 tid=0x00007f9a60002000 nid=0x4c59 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"pool-1-thread-2" #45 prio=5 os_prio=0 tid=0x00007f9a885db000 nid=0x4c4d waiting for monitor entry [0x00007f9a64d01000]
   java.lang.Thread.State: BLOCKED (on object monitor)
        at com.ssm.biz.thread.Blocked.run(Blocked.java:12)
        - waiting to lock <0x00000000ee2509d0> (a java.lang.Object)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:748)

"pool-1-thread-1" #44 prio=5 os_prio=0 tid=0x00007f9a885da800 nid=0x4c4c waiting on condition [0x00007f9a64e02000]
   java.lang.Thread.State: RUNNABLE
        at java.lang.Integer.valueOf(Integer.java:832)
        at com.ssm.biz.thread.Blocked.run(Blocked.java:16)
        - locked <0x00000000ee2509d0> (a java.lang.Object)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:748)

"ajp-nio-8009-AsyncTimeout" #42 daemon prio=5 os_prio=0 tid=0x00007f9a882b0000 nid=0x4c3e waiting on condition [0x00007f9a55f07000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
        at java.lang.Thread.sleep(Native Method)
        at org.apache.coyote.AbstractProtocol$AsyncTimeout.run(AbstractProtocol.java:1149)
        at java.lang.Thread.run(Thread.java:748)
  1. 线程状态24 25
线程状态 产生动作 堆栈信息 状态含义 备注信息
NEW new Thread 线程已经创建,但未调用start()方法 jstack命令不会列出处于此状态的线程信息
RUNNABLE start() java.lang.Thread.State: RUNNABLE
Executor.execute()
BLOCKED synchronize(lock) java.lang.Thread.State: BLOCKED (on object monitor) 正在等待一个monitor lock 通常情况下,是因为本线程与其他线程公用了一个锁。其他在线程正在使用这个锁进入某个synchronized同步方法块或者方法,而本线程进入这个同步代码块也需要这个锁,最终导致本线程处于阻塞状态
WAITING java.lang.Thread.State: WAITING (on object monitor) Object.wait
Thread.join
LockSupport.park java.lang.Thread.State: WAITING (parking)
TIMED_WAITING Thread.sleep java.lang.Thread.State: TIMED_WAITING (sleeping)
Object.wait java.lang.Thread.State: TIMED_WAITING (on object monitor)
Thread.join with timeout
LockSupport.parkNanos java.lang.Thread.State: TIMED_WAITING (parking)
LockSupport.parkUntil java.lang.Thread.State: TIMED_WAITING (parking)
TERMINATED 线程终止

JDK 命令行工具_第11张图片

  1. java.lang.Thread.State: WAITING 26
    1. 多线程并发运行争抢同一个锁资源
    2. on object monitoron ,empty set 队列中的线程,等待获取 monitor
    3. in Object.wait() ,wait set 队列中的线程,已经获取 monitor 但运行过程中需要其他资源,所以暂时放弃 monitor 等资源充足后再重新争抢 monitor

十二、jconsole与jvisualvm27


十一、DEMO

  1. 部署环境
    1. Windows
      1. 启动 Tomcat
      2. 运行 cmd --> tasklist --> 查找 java.exe 进程对应编号
      3. JPS 查看 Java 相关进程编号
      4. 执行上述命令
    2. Linux
      1. 打包 mvn package --> xxx.war
      2. 解压 tomcat/webapp/Root

  1. JDK 工具 ↩︎

  2. JDK中的命令行工具 ↩︎

  3. JIT——即时编译的原理 ↩︎

  4. Hotspot JVM的常用选项 ↩︎

  5. 深入理解Java语言 ↩︎

  6. TM (商标标志) ↩︎

  7. Sun HotSpot VM ↩︎

  8. Java内存与垃圾回收调优 ↩︎

  9. java jps 命令详解 ↩︎

  10. JPS ↩︎

  11. jinfo命令使用 ↩︎

  12. jstat命令使用 ↩︎

  13. java命令–jmap命令使用 ↩︎

  14. IDEA用maven创建springMVC项目和配置 ↩︎

  15. Class文件格式实战:使用ASM动态生成class文件 ↩︎

  16. 内存泄漏检测分析工具MAT(Memory Analyzer Tool)的使用 ↩︎

  17. Java程序内存分析:使用mat工具分析内存占用 ↩︎

  18. 7.1 :OutOfMemoryError,Java堆溢出了,这表明程序有严重的问题。我们需要找造成OutOfMemoryError原因。一般有两种情况 ↩︎

  19. Java Heap dump文件分析工具jhat简介 ↩︎

  20. jdk工具之jhat命令(Java Heap Analyse Tool 虚拟机堆转储快照分析工具)、jhat之一:对dump的结果在浏览器上展示 ↩︎

  21. JVM源码分析之synchronized实现 ↩︎

  22. Linux线程优先级 ↩︎

  23. 如何使用jstack分析线程状态 ↩︎

  24. jstack ↩︎

  25. jstack简介 ↩︎

  26. 三、jdk工具之jstack(Java Stack Trace) ↩︎

  27. jconsole与jvisualvm ↩︎

你可能感兴趣的:(性能调优)