JVM监控:JVM监控指标、JVM监控界面实现、Java监控JVM

18 篇文章 12 订阅
5 篇文章 1 订阅

本文概要:

           1、监控JVM的哪些指标;

           2、一目了然的JVM监控的UI界面;

           3、Java代码获取JVM监控状态。

 

1、监控JVM的哪些指标

                javaVersion                                        /** Java版本号 */
                runTime                                                /** 程序运行时间(ms) */
                loadedClassCount                            /** JVM当前加载类数量 */
                unloadedClassCount                        /** JVM已卸载类数量 */
                heapTotal                                            /** 堆内存大小(字节) */
                heapUsed                                            /** 堆内存已使用(字节) */
                heapUsedPercent                                /** 堆内存使用率 */
                nonHeapTotal                                    /** 堆外内存大小(字节) */
                nonHeapUsed                                        /** 堆外内存已使用(字节) */
                nonHeapUsedPercent                        /** 堆外内存使用率 */
                edenTotal                                            /** Eden区大小(字节) */
                edenUsed                                            /** Eden区已使用(字节) */
                edenUsedPercent                                /** Eden区使用率 */
                edenPeakUsedPercent                        /** Eden区使用率峰值(从上次采集统计) */
                survivorTotal                                    /** Survivor区大小(字节) */
                survivorUsed                                    /** Survivor区已使用(字节) */
                survivorUsedPercent                        /** Survivor区已使用率 */
                survivorPeakUsedPercent                /** Survivor区已使用率峰值(从上次采集统计) */
                oldTotal                                            /** 老区大小(字节) */
                oldUsed                                                /** 老区已使用(字节) */
                oldUsedPercent                                /** 老区已使用率峰值 */
                oldPeakUsedPercent                        /** 老区已使用率峰值(从上次采集统计) */
                permTotal                                            /** 永久区大小(字节) */
                permUsed                                            /** 永久区已使用(字节) */
                permUsedPercent                                /** 永久区使用率 */
                permPeakUsedPercent                        /** 永久区使用率峰值(从上次采集统计) */
                codeCacheTotal                                /** CodeCache区大小(字节) */
                codeCacheUsed                                    /** CodeCache区已使用(字节) */
                codeCacheUsedPercent                    /** CodeCache区使用率 */
                codeCachePeakUsedPercent            /** CodeCache区使用率峰值(从上次采集统计) */
                ygcName                                                /** young gc名称 */
                ygc                                                        /** young gc次数 */
                ygcTime                                                /** young gc总时间 (ms)*/
                fgcName                                                /** full gc名称 */
                fgc                                                        /** full gc次数 */
                fgcTime                                                /** full gc总时间 (ms)*/
                threadCount                                        /** JVM当前线程数量 */
                threadPeakCount                                /** JVM线程数量峰值 */
                userThreadCount                                /** JVM当前用户线程数量 */
                deadLockedThreadCount                    /** JVM死锁线程数量 */

 

2、一目了然的JVM监控的UI界面

3、Java代码获取JVM监控状态

    前面有一篇文章是用Python获取JVM状态数据的《JVM监控:python脚本JMX获取JVM状态》,这里用Java代码获取JVM状态数据,可以在自己的应用程序里定时运行获取JVM状态数据,测试兼容JDK1.7/1.8。

package com.tjy.util;

import java.lang.management.GarbageCollectorMXBean;
import java.lang.management.ManagementFactory;
import java.util.ArrayList;
import java.util.List;

/**
 * 类描述:JVM GC信息工具类
 * 
 **/
public class JVMGCUtils {
	static private GarbageCollectorMXBean youngGC;
    static private GarbageCollectorMXBean fullGC; 

    static{
    	List<GarbageCollectorMXBean> gcMXBeanList = ManagementFactory.getGarbageCollectorMXBeans();        
        for (final GarbageCollectorMXBean gcMXBean : gcMXBeanList) {
			String gcName = gcMXBean.getName();
			if(gcName==null) {
				continue;
			}
			//G1 Old Generation
			//Garbage collection optimized for short pausetimes Old Collector
			//Garbage collection optimized for throughput Old Collector
			//Garbage collection optimized for deterministic pausetimes Old Collector
			//G1 Young Generation
			//Garbage collection optimized for short pausetimes Young Collector
			//Garbage collection optimized for throughput Young Collector
			//Garbage collection optimized for deterministic pausetimes Young Collector
            if (fullGC == null &&
            	(gcName.endsWith("Old Collector")
            	|| "ConcurrentMarkSweep".equals(gcName) 
                || "MarkSweepCompact".equals(gcName) 
                || "PS MarkSweep".equals(gcName))
            ) {
                fullGC = gcMXBean;
            } else if (youngGC == null &&
            		(gcName.endsWith("Young Generation")
            		|| "ParNew".equals(gcName) 
                    || "Copy".equals(gcName) 
                    || "PS Scavenge".equals(gcName)) 
            ) {
                youngGC = gcMXBean;
            }
        }
    }//static

    //YGC名称
    static public String getYoungGCName() {
        return youngGC == null ? "" : youngGC.getName();
    }
    
    //YGC总次数
    static public long getYoungGCCollectionCount() {
        return youngGC == null ? 0 : youngGC.getCollectionCount();
    }

    //YGC总时间
    static public long getYoungGCCollectionTime() {
        return youngGC == null ? 0 : youngGC.getCollectionTime();
    }

    //FGC名称
    static public String getFullGCName() {
        return fullGC == null ? "" : fullGC.getName();
    }
    
    //FGC总次数
    static public long getFullGCCollectionCount() {
        return fullGC == null ? 0 : fullGC.getCollectionCount();
    }

    //FGC总次数
    static public long getFullGCCollectionTime() {
        return fullGC == null ? 0 : fullGC.getCollectionTime();
    }
    
    public static void main(String[] args) {
    	List<List<Long>> listRoot = new ArrayList<List<Long>>();
    	for(;;) {
    		System.out.println("=======================================================================");
	        System.out.println("getYoungGCName: " + JVMGCUtils.getYoungGCName());
	        System.out.println("getYoungGCCollectionCount: " + JVMGCUtils.getYoungGCCollectionCount());
	        System.out.println("getYoungGCCollectionTime: " + JVMGCUtils.getYoungGCCollectionTime());
	        System.out.println("getFullGCName: " + JVMGCUtils.getFullGCName());
	        System.out.println("getFullGCCollectionCount: " + JVMGCUtils.getFullGCCollectionCount());
	        System.out.println("getFullGCCollectionTime: " + JVMGCUtils.getFullGCCollectionTime());
	        List<Long> list = new ArrayList<Long>(1000);
	        listRoot.add(list);
	        try {	        	
				Thread.sleep(3000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
	        if(list.size() > 1) {
	        	list.remove(0);
	        }
	        Runtime.getRuntime().gc();
    	}
    }
}
package com.tjy.util;

import java.lang.management.ClassLoadingMXBean;
import java.lang.management.CompilationMXBean;
import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import java.util.Properties;

/**
 * 类描述:JVM信息工具类
 * 
 **/
public class JVMInfoUtils {
    static private RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean();
    static private ClassLoadingMXBean classLoad = ManagementFactory.getClassLoadingMXBean();
    //可能为null
    static private CompilationMXBean compilation = ManagementFactory.getCompilationMXBean();
    static private Properties properties = System.getProperties();

	/**
	 * 获取JVM进程PID
	 * @return
	 */
	public static String getPID() {
		String pid = System.getProperty("pid");
		if (pid == null) {
	        String name = runtime.getName();
	        if(name != null) {
	        	pid = name.split("@")[0]; 
	        	System.setProperty("pid", pid);        	                    	
	        } 	        
		}
		return pid;
	}
	
    /**
     * 获取JVM规范名称
     * @return
     */
    static public String getJVMSpecName() {
        return runtime.getSpecName();
    }

    /**
     * 获取JVM规范运营商
     * @return
     */
    static public String getJVMSpecVendor() {
        return runtime.getSpecVendor();
    }

    /**
     * 获取JVM规范版本(如:1.7)
     * @return
     */
    static public String getJVMSpecVersion() {
        return runtime.getSpecVersion();
    }

    /**
     * 获取JVM名称
     * @return
     */
    static public String getJVMName() {
        return runtime.getVmName();
    }

    /**
     * 获取Java的运行环境版本(如:1.7.0_67)
     * @return
     */
    static public String getJavaVersion() {
        return getSystemProperty("java.version");
    }
    
    /**
     * 获取JVM运营商
     * @return
     */
    static public String getJVMVendor() {
        return runtime.getVmVendor();
    }

    /**
     * 获取JVM实现版本(如:25.102-b14)
     * @return
     */
    static public String getJVMVersion() {
        return runtime.getVmVersion();
    }

    /**
     * 获取JVM启动时间
     * @return
     */
    static public long getJVMStartTimeMs() {
        return runtime.getStartTime();
    }

    /**
     * 获取JVM运行时间
     * @return
     */
    static public long getJVMUpTimeMs() {
        return runtime.getUptime();
    }

    /**
     * 获取JVM当前加载类总量
     * @return
     */
    static public long getJVMLoadedClassCount() {
        return classLoad.getLoadedClassCount();
    }

    /**
     * 获取JVM已卸载类总量
     * @return
     */
    static public long getJVMUnLoadedClassCount() {
        return classLoad.getUnloadedClassCount();
    }

    /**
     * 获取JVM从启动到现在加载类总量
     * @return
     */
    static public long getJVMTotalLoadedClassCount() {
        return classLoad.getTotalLoadedClassCount();
    }

    /**
     * 获取JIT编译器名称
     * @return
     */
    static public String getJITName() {
        return null == compilation ? "" : compilation.getName();
    }

    /**
     * 获取JIT总编译时间
     * @return
     */
    static public long getJITTimeMs() {
        if (null!=compilation && compilation.isCompilationTimeMonitoringSupported()) {
            return compilation.getTotalCompilationTime();
        }
        return -1;
    }

    /**
     * 获取指定key的属性值
     * @param key
     * @return
     */
    static public String getSystemProperty(String key) {
        return properties.getProperty(key);
    }

    static public Properties getSystemProperty() {
        return properties;
    }
}
package com.tjy.util;

import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.MemoryPoolMXBean;
import java.lang.management.MemoryUsage;
import java.util.ArrayList;
import java.util.List;

/**
 * 类描述:JVM内存信息工具类
 * 
 **/
public class JVMMemoryUtils {
    static private MemoryMXBean memoryMXBean;
    static private MemoryPoolMXBean edenSpaceMxBean;
    static private MemoryPoolMXBean survivorSpaceMxBean;
    static private MemoryPoolMXBean oldGenMxBean;
    static private MemoryPoolMXBean permGenMxBean;
    static private MemoryPoolMXBean codeCacheMxBean;
    
	/**
	 * JVM内存区域使用情况。</br>
	 * <pre>
	 * init:初始内存大小(字节)
	 * used:当前使用内存大小(字节)
	 * committed:已经申请分配的内存大小(字节)
	 * max:最大内存大小(字节)
	 * usedPercent:已经申请分配内存与最大内存大小的百分比
	 * </pre>
	 * @author tangjiyu
	 */
	static public class JVMMemoryUsage {
		//初始内存大小(字节)
	    private long init;
	    //当前使用内存大小(字节)
	    private long used;
	    //已经申请分配的内存大小(字节)
	    private long committed;
	    //最大内存大小(字节)
	    private long max;
	    //已经申请分配内存与最大内存大小的百分比
	    private float usedPercent;
	    
	    public JVMMemoryUsage(MemoryUsage memoryUsage) {
	    	this.setMemoryUsage(memoryUsage);
	    	//this(memoryUsage.getInit(), memoryUsage.getUsed(), memoryUsage.getCommitted(), memoryUsage.getMax());
		}
	    
		public JVMMemoryUsage(long init, long used, long committed, long max) {
			super();			
			this.setMemoryUsage(init, used, committed, max);
		}
		
		private void setMemoryUsage(MemoryUsage memoryUsage) {
	    	if(memoryUsage!=null) {
	    		this.setMemoryUsage(memoryUsage.getInit(), memoryUsage.getUsed(), memoryUsage.getCommitted(), memoryUsage.getMax());
	    	} else {
	    		this.setMemoryUsage(0, 0, 0, 0);
	    	}
		}
		
		private void setMemoryUsage(long init, long used, long committed, long max) {
			this.init = init;
			this.used = used;		
			this.committed = committed;		
			this.max = max;
			if(this.used>0 && max>0) {
				this.usedPercent = used * Float.valueOf("1.0") / max;
			} else {
				this.usedPercent = 0;
			}
		}
		
		public long getInit() {
			return init;
		}
		public long getUsed() {
			return used;
		}
		public long getCommitted() {
			return committed;
		}
		public long getMax() {
			return max;
		}
		public float getUsedPercent() {
			return usedPercent;
		}
		
		@Override
		public String toString() {
			StringBuffer buf = new StringBuffer();
		    buf.append("init = " + init + "(" + (init >> 10) + "K) ");
		    buf.append("used = " + used + "(" + (used >> 10) + "K) ");
		    buf.append("committed = " + committed + "(" +
		               (committed >> 10) + "K) " );
		    buf.append("max = " + max + "(" + (max >> 10) + "K)");
		    buf.append("usedPercent = " + usedPercent);
		    return buf.toString();
		}	
	}
	
    static {
        memoryMXBean = ManagementFactory.getMemoryMXBean();
        
        List<MemoryPoolMXBean> memoryPoolMXBeanList = ManagementFactory.getMemoryPoolMXBeans();        
        for (final MemoryPoolMXBean memoryPoolMXBean : memoryPoolMXBeanList) {
			String poolName = memoryPoolMXBean.getName();
			if(poolName==null) {
				continue;
			}
			// 官方JVM(HotSpot)提供的MemoryPoolMXBean
			// JDK1.7/1.8 Eden区内存池名称: "Eden Space" 或  "PS Eden Space"、 “G1 Eden Space”(和垃圾收集器有关)
			// JDK1.7/1.8 Survivor区内存池名称:"Survivor Space" 或 "PS Survivor Space"、“G1 Survivor Space”(和垃圾收集器有关)
			// JDK1.7  老区内存池名称: "Tenured Gen" 
			// JDK1.8  老区内存池名称:"Old Gen" 或 "PS Old Gen"、“G1 Old Gen”(和垃圾收集器有关)
			// JDK1.7  方法/永久区内存池名称: "Perm Gen" 或 "PS Perm Gen"(和垃圾收集器有关)
			// JDK1.8  方法/永久区内存池名称:"Metaspace"(注意:不在堆内存中)
			// JDK1.7/1.8  CodeCache区内存池名称: "Code Cache" 
			if (edenSpaceMxBean==null && poolName.endsWith("Eden Space")) {
				edenSpaceMxBean = memoryPoolMXBean;
			} else if (survivorSpaceMxBean==null && poolName.endsWith("Survivor Space")) {
				survivorSpaceMxBean = memoryPoolMXBean;
			} else if (oldGenMxBean==null && (poolName.endsWith("Tenured Gen") || poolName.endsWith("Old Gen"))) {
				oldGenMxBean = memoryPoolMXBean;
			} else if (permGenMxBean==null && (poolName.endsWith("Perm Gen") || poolName.endsWith("Metaspace"))) {
				permGenMxBean = memoryPoolMXBean;
			}  else if (codeCacheMxBean==null && poolName.endsWith("Code Cache")) {
				codeCacheMxBean = memoryPoolMXBean;
			} 
		}
    }// static

	
    /**
     * 获取堆内存情况
     * @return 不能获取到返回null
     */
    static public JVMMemoryUsage getHeapMemoryUsage() {
    	if(memoryMXBean!=null) {
    		final MemoryUsage usage =memoryMXBean.getHeapMemoryUsage();
    		if(usage!=null) {
    			return new JVMMemoryUsage(usage);
    		}
    	}
        return null;
    }

    /**
     * 获取堆外内存情况
     * @return 不能获取到返回null
     */
    static public JVMMemoryUsage getNonHeapMemoryUsage() {
    	if(memoryMXBean!=null) {
    		final MemoryUsage usage =memoryMXBean.getNonHeapMemoryUsage();
    		if(usage!=null) {
    			return new JVMMemoryUsage(usage);
    		}
    	}
        return null;
    }
    
    /**
     * 获取Eden区内存情况
     * @return 不能获取到返回null
     */
    static public JVMMemoryUsage getEdenSpaceMemoryUsage() {
    	return getMemoryPoolUsage(edenSpaceMxBean);
    }
    
    /**
     * 获取Eden区内存峰值(从启动或上一次重置开始统计),并重置
     * @return 不能获取到返回null
     */
    static public JVMMemoryUsage getAndResetEdenSpaceMemoryPeakUsage() {
    	return getAndResetMemoryPoolPeakUsage(edenSpaceMxBean);
    }
     
    /**
     * 获取Survivor区内存情况
     * @return 不能获取到返回null
     */
    static public JVMMemoryUsage getSurvivorSpaceMemoryUsage() {
    	return getMemoryPoolUsage(survivorSpaceMxBean);
    }
    
    /**
     * 获取Survivor区内存峰值(从启动或上一次重置开始统计),并重置
     * @return 不能获取到返回null
     */
    static public JVMMemoryUsage getAndResetSurvivorSpaceMemoryPeakUsage() {
    	return getAndResetMemoryPoolPeakUsage(survivorSpaceMxBean);
    }
    
    /**
     * 获取老区内存情况
     * @return 不能获取到返回null
     */
    static public JVMMemoryUsage getOldGenMemoryUsage() {
    	return getMemoryPoolUsage(oldGenMxBean);
    }
    
    /**
     * 获取老区内存峰值(从启动或上一次重置开始统计),并重置
     * @return 不能获取到返回null
     */
    static public JVMMemoryUsage getAndResetOldGenMemoryPeakUsage() {
    	return getAndResetMemoryPoolPeakUsage(oldGenMxBean);
    }
    
    /**
     * 获取永久区/方法区内存情况
     * @return 不能获取到返回null
     */
    static public JVMMemoryUsage getPermGenMemoryUsage() {
    	return getMemoryPoolUsage(permGenMxBean);
    }

    /**
     * 获取永久区/方法区内存峰值(从启动或上一次重置开始统计),并重置
     * @return 不能获取到返回null
     */
    static public JVMMemoryUsage getAndResetPermGenMemoryPeakUsage() {
    	return getAndResetMemoryPoolPeakUsage(permGenMxBean);
    }
    
    /**
     * 获取CodeCache区内存情况
     * @return 不能获取到返回null
     */
    static public JVMMemoryUsage getCodeCacheMemoryUsage() {
    	return getMemoryPoolUsage(codeCacheMxBean);
    }
    
    /**
     * 获取CodeCache区内存峰值(从启动或上一次重置开始统计),并重置
     * @return 不能获取到返回null
     */
    static public JVMMemoryUsage getAndResetCodeCacheMemoryPeakUsage() {
    	return getAndResetMemoryPoolPeakUsage(codeCacheMxBean);
    }
   
    static private JVMMemoryUsage getMemoryPoolUsage(MemoryPoolMXBean memoryPoolMXBean) {
    	if(memoryPoolMXBean!=null) {
			final MemoryUsage usage = memoryPoolMXBean.getUsage();
			if(usage!=null) {
				return new JVMMemoryUsage(usage);
			}
    	}
		return null;
	}
    
    static private JVMMemoryUsage getAndResetMemoryPoolPeakUsage(MemoryPoolMXBean memoryPoolMXBean) {
    	if(memoryPoolMXBean!=null) {
			final MemoryUsage usage = memoryPoolMXBean.getPeakUsage();
			if(usage!=null) {
				memoryPoolMXBean.resetPeakUsage();
				return new JVMMemoryUsage(usage);
			}
    	}
		return null;
	}

    public static void main(String[] args) {
    	List<List<Long>> listRoot = new ArrayList<List<Long>>();
    	for(;;) {
    		System.out.println("=======================================================================");
	        System.out.println("getHeapMemoryUsage: " + JVMMemoryUtils.getHeapMemoryUsage());
	        System.out.println("getNonHeapMemoryUsage: " + JVMMemoryUtils.getNonHeapMemoryUsage());
	        System.out.println("getEdenSpaceMemoryUsage: " + JVMMemoryUtils.getEdenSpaceMemoryUsage());
	        System.out.println("getAndResetEdenSpaceMemoryPeakUsage: " + JVMMemoryUtils.getAndResetEdenSpaceMemoryPeakUsage());
	        System.out.println("getSurvivorSpaceMemoryUsage: " + JVMMemoryUtils.getSurvivorSpaceMemoryUsage());
	        System.out.println("getAndResetSurvivorSpaceMemoryPeakUsage: " + JVMMemoryUtils.getAndResetSurvivorSpaceMemoryPeakUsage());
	        System.out.println("getOldGenMemoryUsage: " + JVMMemoryUtils.getOldGenMemoryUsage());
	        System.out.println("getAndResetOldGenMemoryPeakUsage: " + JVMMemoryUtils.getAndResetOldGenMemoryPeakUsage());
	        System.out.println("getPermGenMemoryUsage: " + JVMMemoryUtils.getPermGenMemoryUsage());
	        System.out.println("getAndResetPermGenMemoryPeakUsage: " + JVMMemoryUtils.getAndResetPermGenMemoryPeakUsage());
	        System.out.println("getCodeCacheMemoryUsage: " + JVMMemoryUtils.getCodeCacheMemoryUsage());
	        System.out.println("getAndResetCodeCacheMemoryPeakUsage: " + JVMMemoryUtils.getAndResetCodeCacheMemoryPeakUsage());
	        List<Long> list = new ArrayList<Long>(10000);
	        listRoot.add(list);
	        try {	        	
				Thread.sleep(3000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
	        
	        if(list.size() > 1) {
	        	list.remove(0);
	        }
	        Runtime.getRuntime().gc();
    	}
    }
}

 

package com.tjy.util;

import java.lang.management.ManagementFactory;
import java.lang.management.ThreadMXBean;

/**
 * 类描述:JVM 线程信息工具类
 * 
 **/
public class JVMThreadUtils {
    static private ThreadMXBean threadMXBean;

    static {
        threadMXBean = ManagementFactory.getThreadMXBean();
    }

    /**
     * Daemon线程总量
     * @return
     */
    static public int getDaemonThreadCount() {
        return threadMXBean.getDaemonThreadCount();
    }

    /**
     * 当前线程总量
     * @return
     */
    static public int getThreadCount() {
        return threadMXBean.getThreadCount();
    }
    
    /**
     * 获取线程数量峰值(从启动或resetPeakThreadCount()方法重置开始统计)
     * @return
     */
    static public int getPeakThreadCount() {
        return threadMXBean.getPeakThreadCount();
    }
    
    /**
     * 获取线程数量峰值(从启动或resetPeakThreadCount()方法重置开始统计),并重置
     * @return
     * @Throws java.lang.SecurityException - if a security manager exists and the caller does not have ManagementPermission("control").
     */
    static public int getAndResetPeakThreadCount() {
    	int count = threadMXBean.getPeakThreadCount();
    	resetPeakThreadCount();
        return count;
    }
    
    /**
     * 重置线程数量峰值
     * @Throws java.lang.SecurityException - if a security manager exists and the caller does not have ManagementPermission("control").
     */
    static public void resetPeakThreadCount() {
        threadMXBean.resetPeakThreadCount();
    }
    
    /**
     * 死锁线程总量
     * @return
     * @Throws IllegalStateException 没有权限或JVM不支持的操作
     */
    static public int getDeadLockedThreadCount() {
        try {
            long[] deadLockedThreadIds = threadMXBean.findDeadlockedThreads();
            if (deadLockedThreadIds == null) {
                return 0;
            }
            return deadLockedThreadIds.length;
        } catch (Exception e) {
            throw new IllegalStateException(e.getMessage(), e);
        }
    }
    
    public static void main(String[] args) {
    	for(;;) {
    		System.out.println("=======================================================================");
	        System.out.println("getDaemonThreadCount: " + JVMThreadUtils.getDaemonThreadCount());
	        System.out.println("getNonHeapMemoryUsage: " + JVMThreadUtils.getThreadCount());
	        System.out.println("getPeakThreadCountAndReset: " + JVMThreadUtils.getAndResetPeakThreadCount());
	        System.out.println("getDeadLockedThreadCount: " + JVMThreadUtils.getDeadLockedThreadCount());
	        try {	        	
				Thread.sleep(5000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
    	}
    }
}
package com.tjy.task.impl.app;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import com.tjy.util.JVMGCUtils;
import com.tjy.util.JVMInfoUtils;
import com.tjy.util.JVMMemoryUtils;
import com.tjy.util.JVMMemoryUtils.JVMMemoryUsage;
import com.tjy.util.JVMThreadUtils;

/**
 * 
 * 应用状态监控,包括应用类型,版本,所在的tomcat名以及数据库连接等信息(代码有删减)
 * 
 * 
 */
public class ApplicationMonitorTask extends AbstractMonitorTask<ApplicationMonitorMessage> {

	@Override
	protected ApplicationMonitorMessage doRun() {
		return this.createMessage();
	}

	private ApplicationMonitorMessage createMessage() {
		ApplicationMonitorMessage message = new ApplicationMonitorMessage();
		// APP
		message.setVersion(ErlangMonitorConfigManager.getConfig().getAppVersion());
		// JVM
		setJVMInfo(message);
		// DB
		setDBInfo(message);
		return message;
	}

	private void setJVMInfo(ApplicationMonitorMessage message) {
		try {
			message.setPid(Integer.parseInt(JVMInfoUtils.getPID()));
		} catch (Exception e) {
		}
		message.setJavaVersion(JVMInfoUtils.getJavaVersion());
		message.setRunTime(JVMInfoUtils.getJVMUpTimeMs());
		message.setLoadedClassCount(JVMInfoUtils.getJVMLoadedClassCount());
		message.setUnloadedClassCount(JVMInfoUtils.getJVMUnLoadedClassCount());
		JVMMemoryUsage heapMemoryUsage = JVMMemoryUtils.getHeapMemoryUsage();
		if (heapMemoryUsage != null) {
			message.setHeapTotal(heapMemoryUsage.getMax());
			message.setHeapUsed(heapMemoryUsage.getUsed());
			message.setHeapUsedPercent(heapMemoryUsage.getUsedPercent());
		}
		JVMMemoryUsage nonHeapMemoryUsage = JVMMemoryUtils.getNonHeapMemoryUsage();
		if (nonHeapMemoryUsage != null) {
			message.setNonHeapTotal(nonHeapMemoryUsage.getMax());
			message.setNonHeapUsed(nonHeapMemoryUsage.getUsed());
			message.setNonHeapUsedPercent(nonHeapMemoryUsage.getUsedPercent());
		}
		JVMMemoryUsage edenMemoryUsage = JVMMemoryUtils.getEdenSpaceMemoryUsage();
		if (edenMemoryUsage != null) {
			message.setEdenTotal(edenMemoryUsage.getMax());
			message.setEdenUsed(edenMemoryUsage.getUsed());
			message.setEdenUsedPercent(edenMemoryUsage.getUsedPercent());
		}
		JVMMemoryUsage edenPeakMemoryUsage = JVMMemoryUtils.getAndResetEdenSpaceMemoryPeakUsage();
		if (edenPeakMemoryUsage != null) {
			message.setEdenPeakUsedPercent(edenPeakMemoryUsage.getUsedPercent());
		}
		JVMMemoryUsage survivorMemoryUsage = JVMMemoryUtils.getSurvivorSpaceMemoryUsage();
		if (survivorMemoryUsage != null) {
			message.setSurvivorTotal(survivorMemoryUsage.getMax());
			message.setSurvivorUsed(survivorMemoryUsage.getUsed());
			message.setSurvivorUsedPercent(survivorMemoryUsage.getUsedPercent());
		}
		JVMMemoryUsage survivorPeakMemoryUsage = JVMMemoryUtils.getAndResetSurvivorSpaceMemoryPeakUsage();
		if (survivorPeakMemoryUsage != null) {
			message.setSurvivorPeakUsedPercent(survivorPeakMemoryUsage.getUsedPercent());
		}
		JVMMemoryUsage oldGenMemoryUsage = JVMMemoryUtils.getOldGenMemoryUsage();
		if (oldGenMemoryUsage != null) {
			message.setOldTotal(oldGenMemoryUsage.getMax());
			message.setOldUsed(oldGenMemoryUsage.getUsed());
			message.setOldUsedPercent(oldGenMemoryUsage.getUsedPercent());
		}
		JVMMemoryUsage oldGenPeakMemoryUsage = JVMMemoryUtils.getAndResetOldGenMemoryPeakUsage();
		if (oldGenPeakMemoryUsage != null) {
			message.setOldPeakUsedPercent(oldGenPeakMemoryUsage.getUsedPercent());
		}
		JVMMemoryUsage permGenMemoryUsage = JVMMemoryUtils.getPermGenMemoryUsage();
		if (permGenMemoryUsage != null) {
			message.setPermTotal(permGenMemoryUsage.getMax());
			message.setPermUsed(permGenMemoryUsage.getUsed());
			message.setPermUsedPercent(permGenMemoryUsage.getUsedPercent());
		}
		JVMMemoryUsage permGenPeakMemoryUsage = JVMMemoryUtils.getAndResetPermGenMemoryPeakUsage();
		if (permGenPeakMemoryUsage != null) {
			message.setPermPeakUsedPercent(permGenPeakMemoryUsage.getUsedPercent());
		}
		JVMMemoryUsage codeCacheGenMemoryUsage = JVMMemoryUtils.getCodeCacheMemoryUsage();
		if (codeCacheGenMemoryUsage != null) {
			message.setCodeCacheTotal(codeCacheGenMemoryUsage.getMax());
			message.setCodeCacheUsed(codeCacheGenMemoryUsage.getUsed());
			message.setCodeCacheUsedPercent(codeCacheGenMemoryUsage.getUsedPercent());
		}
		JVMMemoryUsage codeCacheGenPeakMemoryUsage = JVMMemoryUtils.getAndResetCodeCacheMemoryPeakUsage();
		if (codeCacheGenPeakMemoryUsage != null) {
			message.setCodeCachePeakUsedPercent(codeCacheGenPeakMemoryUsage.getUsedPercent());
		}

		message.setYgcName(JVMGCUtils.getYoungGCName());
		message.setYgc(JVMGCUtils.getYoungGCCollectionCount());
		message.setYgcTime(JVMGCUtils.getYoungGCCollectionTime());
		message.setFgcName(JVMGCUtils.getFullGCName());
		message.setFgc(JVMGCUtils.getFullGCCollectionCount());
		message.setFgcTime(JVMGCUtils.getFullGCCollectionTime());

		message.setThreadCount(JVMThreadUtils.getThreadCount());
		message.setThreadPeakCount(JVMThreadUtils.getAndResetPeakThreadCount());
		message.setUserThreadCount(message.getThreadCount() - JVMThreadUtils.getDaemonThreadCount());
		message.setDeadLockedThreadCount(JVMThreadUtils.getDeadLockedThreadCount());
	}

}

 

【参考文档】

          《JVM监控》

  • 6
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
JVM常用监控工具有很多,其中一个重要的工具就是dump分析工具。dump文件是指Java进程的内存快照,可以用于分析Java进程的内存使用情况,了解Java进程内部的情况。 下面介绍几个常用的dump分析工具: 1. jmap jmap是JDK自带的一个命令行工具,可以生成Java进程的内存快照。使用jmap生成dump文件的命令如下: ``` jmap -dump:format=b,file=<filename> <pid> ``` 其中,format=b表示生成二进制格式的dump文件,file=<filename>表示指定保存dump文件的路径和文件名,<pid>表示Java进程的进程ID。 2. jstack jstack也是JDK自带的一个命令行工具,可以打印Java进程的线程堆栈信息。使用jstack生成dump文件的命令如下: ``` jstack -F <pid> > <filename> ``` 其中,-F表示在进程不响应时强制获取线程堆栈信息,<pid>表示Java进程的进程ID,> <filename>表示将线程堆栈信息输出到指定文件。 3. VisualVM VisualVM是一个功能强大的Java监控和分析工具,可以监控和分析本地和远程Java进程。VisualVM可以生成Java进程的各种信息,包括dump文件。使用VisualVM生成dump文件的步骤如下: - 在VisualVM中打开需要生成dump文件的Java进程。 - 选择“Heap Dump”选项卡,点击“Heap Dump”按钮。 - 选择保存dump文件的路径和文件名,点击“Save”按钮。 4. Eclipse Memory Analyzer Eclipse Memory Analyzer是一款功能强大的Java内存分析工具,可以帮助开发人员分析Java进程的内存使用情况。Eclipse Memory Analyzer可以打开各种格式的dump文件,包括使用jmap、jstack和VisualVM生成的dump文件。 以上是常用的dump分析工具,可以帮助开发人员了解Java进程的内存使用情况。同时,需要注意的是,生成dump文件会对Java进程产生一定的影响,需要谨慎使用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值