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.
  • 相关阅读:
    泛型技巧系列:如何提供类型参数之间的转换
    一些支离破碎的泛型反射技巧
    泛型技巧系列:类型字典和Type Traits
    Excel开发:简化工作表中选定区域的操作。
    趣味程序:打印自己代码的程序
    VBF BETA 1.5 发布了
    .NET 2.0 CER学习笔记
    随笔乱入,开心就好
    Cocos2dx for WindowsPhone:开发一个打地鼠游戏(下)
    跨平台网络游戏趋势和优势
  • 原文地址:https://www.cnblogs.com/F017/p/12410075.html
Copyright © 2011-2022 走看看