zoukankan      html  css  js  c++  java
  • jstack的使用

    jstack介绍

    jstack是jdk自带的线程堆栈分析工具,使用该命令可以查看或导出 java 应用程序中线程堆栈信息。

     
     jstack用于生成java虚拟机当前时刻的线程快照。线程快照是当前java虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的是定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待等。 线程出现停顿的时候通过jstack来查看各个线程的调用堆栈,就可以知道没有响应的线程到底在后台做什么事情,或者等待什么资源。 如果java程序崩溃生成core文件,jstack工具可以用来获得core文件的java stack和native stack的信息,从而可以轻松地知道java程序是如何崩溃和在程序何处发生问题。另外,jstack工具还可以附属到正在运行的java程序中,看到当时运行的java程序的java stack和native stack的信息, 如果现在运行的java程序呈现hung的状态,jstack是非常有用的.

    1.使用jstat命令查看堆内存的使用情况
        jstat 命令选项 vmid 间隔时间 查询次数
        
        1.查看当前进程Class类加载的统计
         jstat -class 16184
        
        2.查看编译统计
         jstat -compiler 16184
      
        3.查看垃圾回收统计
         jstat -gc 16184
         
         s0c: 第一个Survivor区域大小
         S1C:第二个Survivor区域的大小
         S0U:第一个Survivor区域使用的大小
         S1U:第二个Survivor区域使用的大小
         EC:Eden区域的大小
         EU:Eden区域的使用大小
         OC:Old区的大小
         OU:Old区使用的大小
         MC:方法区大小
         YGC:年轻代垃圾回收次数
         FGC:年老代垃圾回收次数
       
       2.通过jmap监控内存使用情况
        监控堆内存:jmap -heap 16184

        监控内存中对象的数量及其大小:
         查看所有对象的数量以及大小包括类型:jmap -histo 16184| more
         查看所有对象的数量以及大小包括类型:jmap -histo:live 16184| more
        
        通过jmap导出堆内存使用情况的文件
         jmap -dump:format=b,file=C:Windowsdump.dat 16184
        
        
        通过jhat查看dump文件并且进行分析,启动一个HTTP端口进行访问,通过该端口可以查看到整个应用程序所使用的的所有对象的情况,提供OQL进行检索
         jhat -port 8081 C:Windowsdump.dat
       
       3.MAT分析工具,在工具中可以查看到对象数量以及内存使用的情况,当然可以分析出可能出现问题
        如果问题是正常情况,可以加大内存,如果是非正常情况,手动解决代码问题
       
       4.模拟内存溢出:
        public static void main(String[] args) {
         List<Object> objList=new ArrayList<>();
         for (int i=0;i<10000000;i++){
          String str="";
          for(int j=0;j<1000;j++){
           str+= UUID.randomUUID().toString();
          }
          objList.add(str);
         }
         System.out.println("添加数据成功~");
        }
        参数设置:-Xms8m -Xmx8m -XX:+HeapDumpOnOutOfMemoryError
       ==================================================================================================================
       1.通过jstack监控JVM当中线程的运行情况  jstack 进程ID
        线程抢占CPU资源,当CPU过高时,定位线程,查看线程使用状态
        
        线程状态:
         初始状态:New,线程对象创建出来后,没有调用start方法,线程处于初始状态
         运行状态:
          1.就绪状态:Ready,调用了Start方法,等待CPU分配资源
          2.运行状态:RUNNING,CPU分配资源给该线程,该线程处于运行状态
         阻塞状态 BLOCKED:
          线程获取资源,如果资源获取成功则正常运行,如果资源获取失败,就处于阻塞状态,等待什么时候获取到资源再变为运行状态
         等待状态 WAITING:线程手动调用了wait()方法,或者join()方法,这些方法都是主动进入等待状态,等待状态会将CPU资源让渡
             需要其他线程手动唤醒,notify(),notifyAll()唤起所有的等待线程
         超时等待状态 TIMED_WAITING:与等待状态相同,都是主动进入等待,也是需要其他线程唤醒,但是区别在与超时等待,如果超过了等待时间,则自动唤醒
          Thread.sleep(2000),在休眠等待时间内会将CPU资源让渡,然后等待时间结束自动进入运行状态
         终止状态DIED:线程结束之后的状态
       
       2.手动模拟死锁情况
        public class LockTest {
         //定义资源
         private static Object obj1=new Object();
         private static Object obj2=new Object();
         //线程A:先获取到资源1,然后休眠2s,再获取资源2
         private static class ThreadA implements Runnable{
          @Override
          public void run() {
           synchronized (obj1){
            System.out.println("ThreadA获取到了OBJ1资源");
            try {
             //休眠2s,因为我们要将CPU资源让渡出去,这样线程B就可以先抢占obj2资源
             Thread.sleep(2000);
            } catch (InterruptedException e) {
             e.printStackTrace();
            }
            synchronized (obj2){
             System.out.println("ThreadA获取到了OBJ2资源");
            }
           }
          }
         }
         private static class ThreadB implements Runnable{
          @Override
          public void run() {
           synchronized (obj2){
            System.out.println("ThreadB获取到了OBJ2资源");
            try {
             //休眠2s,因为我们要将CPU资源让渡出去,这样线程B就可以先抢占obj2资源
             Thread.sleep(2000);
            } catch (InterruptedException e) {
             e.printStackTrace();
            }
            synchronized (obj1){
             System.out.println("ThreadA获取到了OBJ1资源");
            }
           }
          }
         }
         public static void main(String[] args) {
          new Thread(new ThreadA()).start();
          new Thread(new ThreadB()).start();
         }
        }
       2.1监控当前程序的线程运行情况
        jstack 进程ID,查看到如下信息:
         Java stack information for the threads listed above:
         ===================================================
         "Thread-1":
           at com.wdksoft.LockTest$ThreadB.run(LockTest.java:41)
           - waiting to lock <0x000000076bc9d060> (a java.lang.Object)
           - locked <0x000000076bc9d070> (a java.lang.Object)
           at java.lang.Thread.run(Thread.java:748)
         "Thread-0":
           at com.wdksoft.LockTest$ThreadA.run(LockTest.java:22)
           - waiting to lock <0x000000076bc9d070> (a java.lang.Object)
           - locked <0x000000076bc9d060> (a java.lang.Object)
           at java.lang.Thread.run(Thread.java:748)
         Found 1 deadlock.
        
  • 相关阅读:
    zbb20181207 springboot @ConfigurationProperties使用
    zbb20181206 logback,lombok 默认日志logback配置解析
    Spring Boot (8) 全局异常处理
    Spring Boot (7) JdbcTemplate访问数据库
    Spring Boot (6) Spring Data JPA
    Spring Boot (4) 静态页面和Thymeleaf模板
    Spring Boot (3) 热部署devtools
    Spring Boot (2) Restful风格接口
    Spring Boot (1) 构建第一个Spring Boot工程
    idea使用maven搭建ssm框架实现登陆商品增删改查
  • 原文地址:https://www.cnblogs.com/mayuan01/p/12409199.html
Copyright © 2011-2022 走看看