zoukankan      html  css  js  c++  java
  • spring监控(九)-JVM内存监控

    概述

    共有加载类、运行时、线程池、内存池和内存回收几大类指标

    加载类

    指标定义类

    @Data
    @NoArgsConstructor
    public class ClassLoadingMetric {
    
        private long loadedClasses;
        private long totalLoadedClasses;
        private long unloadedClasses;
    }

    指标获取类

    public class ClassLoadingProvider {
    
        private ClassLoadingMXBean mbean;
        
        public ClassLoadingProvider(){
            this.mbean = ManagementFactory.getClassLoadingMXBean();
        }
        
        public ClassLoadingMetric getClassLoadingMetrics(){
            ClassLoadingMetric metrics = new ClassLoadingMetric();
            metrics.setLoadedClasses(mbean.getLoadedClassCount());
            metrics.setTotalLoadedClasses(mbean.getTotalLoadedClassCount());
            metrics.setUnloadedClasses(mbean.getUnloadedClassCount());
            return metrics;
        }
    }

    运行时

    指标定义类

    @Data
    @NoArgsConstructor
    public class RuntimeMetric {
        private long startTimes;  // JVM启动时间点
        private long upTime;    // JVM运行时间
        private String specName;// Java虚拟机规范名称 
        private String specVersion;// Java虚拟机规范版本号
        private String vmName;// Java虚拟机名称 
        private String vmVersion;// Java虚拟机版本号
    }

    指标获取类

    public class RuntimeProvider {
        private RuntimeMXBean mbean;
        
        public RuntimeProvider(){
            this.mbean = ManagementFactory.getRuntimeMXBean();
        }
        
        public RuntimeMetric getClassLoadingMetrics(){
            RuntimeMetric  metrics = new RuntimeMetric();
            
            metrics.setStartTimes(mbean.getStartTime());
            metrics.setUpTime(mbean.getUptime());
            metrics.setSpecName(mbean.getSpecName());
            metrics.setSpecVersion(mbean.getSpecVersion());
            metrics.setVmName(mbean.getVmName());
            metrics.setVmVersion(mbean.getVmVersion());
            
            return metrics;
        }
    }

    线程池

    指标定义类

    @Data
    @NoArgsConstructor
    public class ThreadMetric {
    
        private long totalThreads;  // 自JVM启动以来启动的所有线程数
        private long livingThreads;    // 当前activing的线程
        private long peakThreads;    // 线程数峰值
        private long daemonThreads;    // 守护线程数
    }

    指标获取类

    public class ThreadProvider {
        private ThreadMXBean mbean;
        
        public ThreadProvider(){
            this.mbean = ManagementFactory.getThreadMXBean();
        }
        
        public ThreadMetric getClassLoadingMetrics(){
            ThreadMetric  metrics = new ThreadMetric();
            
            metrics.setDaemonThreads(mbean.getDaemonThreadCount());
            metrics.setPeakThreads(mbean.getPeakThreadCount());
            metrics.setLivingThreads(mbean.getThreadCount());
            metrics.setTotalThreads(mbean.getTotalStartedThreadCount());
            
            return metrics;
        }
    }

    内存池

    JVM内存分为堆栈区和非堆栈区两个部分,这个是固定的。而对于内存池,有不同的实现,而不同的内存池其相应的指标名是不一样,因此应该区分获取。

    JVM内存池指标定义

    @Data
    @NoArgsConstructor
    public class JvmMemoryMetric {
    
        private long heapMax;
        private long heapUsed;
        private long heapAllocated;
    
        private long nonHeapMax;
        private long nonHeapUsed;
        private long nonHeapAllocated;
    
        private long permGenMax;
        private long permGenUsed;
        private long permGenAllocated;
    
        private long codeCacheMax;
        private long codeCacheUsed;
        private long codeCacheAllocated;
    
        private long edenMax;
        private long edenUsed;
        private long edenAllocated;
    
        private long oldMax;
        private long oldUsed;
        private long oldAllocated;
    
        private long survivorMax;
        private long survivorUsed;
        private long survivorAllocated;
    
        private long metaspaceMax;
        private long metaspaceUsed;
        private long metaspaceAllocated;
        
    }

    内存池接口

    public interface MemoryPoolMetricAccessor {
    
        void fetchMemoryPoolMetrics(JvmMemoryMetric memoryMetric);
    
    }

    内存池基础类

    public abstract class MemoryPoolModule implements MemoryPoolMetricAccessor {
        
        private MemoryPoolMXBean[] beans;
    
        public MemoryPoolModule(List<MemoryPoolMXBean> beans) {
            this.beans = beans.toArray(new MemoryPoolMXBean[0]);
        }
    
        @Override
        public void fetchMemoryPoolMetrics(JvmMemoryMetric memoryMetric) {
            
            // 循环每个内存区域,收集每个 MemoryPool 指标
            for (MemoryPoolMXBean bean : beans) {
                String name = bean.getName();
                MemoryUsage usage = bean.getUsage();
                // 获得内存区域类型
                if (contains(getCodeCacheNames(), name)) {
                    memoryMetric.setCodeCacheMax(usage.getMax());
                    memoryMetric.setCodeCacheUsed(usage.getUsed());
                    memoryMetric.setCodeCacheAllocated(usage.getCommitted());
                } else if (contains(getEdenNames(), name)) {
                    memoryMetric.setEdenMax(usage.getMax());
                    memoryMetric.setEdenUsed(usage.getUsed());
                    memoryMetric.setEdenAllocated(usage.getCommitted());
                } else if (contains(getOldNames(), name)) {
                    memoryMetric.setOldMax(usage.getMax());
                    memoryMetric.setOldUsed(usage.getUsed());
                    memoryMetric.setOldAllocated(usage.getCommitted());
                } else if (contains(getSurvivorNames(), name)) {
                    memoryMetric.setSurvivorMax(usage.getMax());
                    memoryMetric.setSurvivorUsed(usage.getUsed());
                    memoryMetric.setSurvivorAllocated(usage.getCommitted());
                } else if (contains(getMetaspaceNames(), name)) {
                    memoryMetric.setMetaspaceMax(usage.getMax());
                    memoryMetric.setMetaspaceUsed(usage.getUsed());
                    memoryMetric.setMetaspaceAllocated(usage.getCommitted());
                } else if (contains(getPermNames(), name)) {
                    memoryMetric.setPermGenMax(usage.getMax());
                    memoryMetric.setPermGenUsed(usage.getUsed());
                    memoryMetric.setPermGenAllocated(usage.getCommitted());
                } else {
                    continue;
                }
            }
        }
    
        private boolean contains(String[] possibleNames, String name) {
            for (String possibleName : possibleNames) {
                if (name.equals(possibleName)) {
                    return true;
                }
            }
            return false;
        }
    
        protected abstract String[] getPermNames();
    
        protected abstract String[] getCodeCacheNames();
    
        protected abstract String[] getEdenNames();
    
        protected abstract String[] getOldNames();
    
        protected abstract String[] getSurvivorNames();
    
        protected abstract String[] getMetaspaceNames();
    }

    CMSCollector内存池类

    public class CMSCollectorModule extends MemoryPoolModule {
        public CMSCollectorModule(List<MemoryPoolMXBean> beans) {
            super(beans);
        }
    
        @Override 
        protected String[] getPermNames() {
            return new String[] {"CMS Perm Gen", "Compressed Class Space"};
        }
    
        @Override 
        protected String[] getCodeCacheNames() {
            return new String[] {"Code Cache"};
        }
    
        @Override 
        protected String[] getEdenNames() {
            return new String[] {"Par Eden Space"};
        }
    
        @Override 
        protected String[] getOldNames() {
            return new String[] {"CMS Old Gen"};
        }
    
        @Override 
        protected String[] getSurvivorNames() {
            return new String[] {"Par Survivor Space"};
        }
    
        @Override 
        protected String[] getMetaspaceNames() {
            return new String[] {"Metaspace"};
        }
    }

    G1内存池类

    public class G1CollectorModule extends MemoryPoolModule {
        public G1CollectorModule(List<MemoryPoolMXBean> beans) {
            super(beans);
        }
    
        @Override 
        protected String[] getPermNames() {
            return new String[] {"G1 Perm Gen", "Compressed Class Space"};
        }
    
        @Override 
        protected String[] getCodeCacheNames() {
            return new String[] {"Code Cache"};
        }
    
        @Override 
        protected String[] getEdenNames() {
            return new String[] {"G1 Eden Space"};
        }
    
        @Override 
        protected String[] getOldNames() {
            return new String[] {"G1 Old Gen"};
        }
    
        @Override 
        protected String[] getSurvivorNames() {
            return new String[] {"G1 Survivor Space"};
        }
    
        @Override 
        protected String[] getMetaspaceNames() {
            return new String[] {"Metaspace"};
        }
    }

    Parallel内存池类

    public class ParallelCollectorModule extends MemoryPoolModule {
    
        public ParallelCollectorModule(List<MemoryPoolMXBean> beans) {
            super(beans);
        }
    
        @Override 
        protected String[] getPermNames() {
            return new String[] {"PS Perm Gen", "Compressed Class Space"};
        }
    
        @Override 
        protected String[] getCodeCacheNames() {
            return new String[] {"Code Cache"};
        }
    
        @Override 
        protected String[] getEdenNames() {
            return new String[] {"PS Eden Space"};
        }
    
        @Override 
        protected String[] getOldNames() {
            return new String[] {"PS Old Gen"};
        }
    
        @Override 
        protected String[] getSurvivorNames() {
            return new String[] {"PS Survivor Space"};
        }
    
        @Override 
        protected String[] getMetaspaceNames() {
            return new String[] {"Metaspace"};
        }
    }

    SerialCollector类

    public class SerialCollectorModule extends MemoryPoolModule {
        public SerialCollectorModule(List<MemoryPoolMXBean> beans) {
            super(beans);
        }
    
        @Override 
        protected String[] getPermNames() {
            return new String[] {"Perm Gen", "Compressed Class Space"};
        }
    
        @Override 
        protected String[] getCodeCacheNames() {
            return new String[] {"Code Cache"};
        }
    
        @Override 
        protected String[] getEdenNames() {
            return new String[] {"Eden Space"};
        }
    
        @Override 
        protected String[] getOldNames() {
            return new String[] {"Tenured Gen"};
        }
    
        @Override 
        protected String[] getSurvivorNames() {
            return new String[] {"Survivor Space"};
        }
    
        @Override 
        protected String[] getMetaspaceNames() {
            return new String[] {"Metaspace"};
        }
    }

    内存池指标获取类

    public class MemoryPoolProvider {
    
        private MemoryPoolMetricAccessor metricAccessor;
        private List<MemoryPoolMXBean> beans;
    
        public MemoryPoolProvider() {
            // 创建 JVM GC 方式对应的 MemoryPoolMetricAccessor对象
            beans = ManagementFactory.getMemoryPoolMXBeans();
            for (MemoryPoolMXBean bean : beans) {
                String name = bean.getName();
                MemoryPoolMetricAccessor accessor = findByBeanName(name);
                if (accessor != null) {
                    metricAccessor = accessor;
                    break;
                }
            }
            if (metricAccessor == null) {
                metricAccessor = new UnknownMemoryPool();
            }
        }
    
        public void fetchMemoryPoolMetrics(JvmMemoryMetric memoryMetric) {
            metricAccessor.fetchMemoryPoolMetrics(memoryMetric);
        }
    
        private MemoryPoolMetricAccessor findByBeanName(String name) {
            if (name.indexOf("PS") > -1) { // ParallelCollector
                //Parallel (Old) collector ( -XX:+UseParallelOldGC )
                return new ParallelCollectorModule(beans);
            } else if (name.indexOf("CMS") > -1) { // CMSCollector
                // CMS collector ( -XX:+UseConcMarkSweepGC )
                return new CMSCollectorModule(beans);
            } else if (name.indexOf("G1") > -1) { // G1Collector
                // G1 collector ( -XX:+UseG1GC )
                return new G1CollectorModule(beans);
            } else if ("Survivor Space".equals(name)) { // SerialCollector
                // Serial collector ( -XX:+UseSerialGC )
                return new SerialCollectorModule(beans);
            } else {
                // Unknown
                return null;
            }
        }
    }

    内存回收

    指标定义类

    @Data
    @NoArgsConstructor
    public class GCMetric {
    
        private long fullGCCount;
        private long fullGCTime;
        private long minorGCCount;
        private long minorGCTime;
    }

    指标获取接口

    public interface GCMetricAccessor {
        GCMetric getGCMetrics();
    }

    指标获取基类

    public abstract class GCModule implements GCMetricAccessor {
        private GarbageCollectorMXBean[] beans;
    
        private volatile long lastMinorGCCount;
        private volatile long lastMinorGCTime;
        private volatile long lastFullGCCount;
        private volatile long lastFullGCTime;
        
        public GCModule(List<GarbageCollectorMXBean> beans) {
            this.beans = beans.toArray(new GarbageCollectorMXBean[0]);
        }
    
        @Override
        public GCMetric getGCMetrics() {
            GCMetric metrics = new GCMetric();
            for (GarbageCollectorMXBean bean : beans) {
                // 获得
                String name = bean.getName();
                if (name.equals(getNewGCName())) {
                    long minorGCCount = bean.getCollectionCount();
                    long minorGCTime = bean.getCollectionTime();
                    metrics.setMinorGCCount(minorGCCount - this.lastMinorGCCount);
                    metrics.setMinorGCTime(minorGCTime - this.lastMinorGCTime);
                    this.lastMinorGCCount = minorGCCount;
                    this.lastMinorGCTime = minorGCTime;
                } else if (name.equals(getOldGCName())) {
                    long fullGCCount = bean.getCollectionCount();
                    long fullGCTime = bean.getCollectionTime();
                    metrics.setFullGCCount(fullGCCount - this.lastFullGCCount);
                    metrics.setFullGCTime(fullGCTime - this.lastFullGCTime);
                    this.lastFullGCCount = fullGCCount;
                    this.lastFullGCTime = fullGCTime;
                } else {
                    continue;
                }
            }
    
            return metrics;
        }
    
        protected abstract String getOldGCName();
    
        protected abstract String getNewGCName();
    }

    CMSGCModule类

    public class CMSGCModule extends GCModule {
        public CMSGCModule(List<GarbageCollectorMXBean> beans) {
            super(beans);
        }
    
        @Override 
        protected String getOldGCName() {
            return "ConcurrentMarkSweep";
        }
    
        @Override 
        protected String getNewGCName() {
            return "ParNew";
        }
    }

    G1GCModule

    public class G1GCModule extends GCModule {
        public G1GCModule(List<GarbageCollectorMXBean> beans) {
            super(beans);
        }
    
        @Override 
        protected String getOldGCName() {
            return "G1 Old Generation";
        }
    
        @Override 
        protected String getNewGCName() {
            return "G1 Young Generation";
        }
    }

    ParallelGCModule

    public class ParallelGCModule extends GCModule {
        public ParallelGCModule(List<GarbageCollectorMXBean> beans) {
            super(beans);
        }
    
        @Override 
        protected String getOldGCName() {
            return "PS MarkSweep";
        }
    
        @Override 
        protected String getNewGCName() {
            return "PS Scavenge";
        }
    
    }

    SerialGCModule

    public class SerialGCModule extends GCModule {
        public SerialGCModule(List<GarbageCollectorMXBean> beans) {
            super(beans);
        }
    
        @Override 
        protected String getOldGCName() {
            return "MarkSweepCompact";
        }
    
        @Override 
        protected String getNewGCName() {
            return "Copy";
        }
    }

    UnknowGC

    public class UnknowGC implements GCMetricAccessor {
        @Override
        public GCMetric getGCMetrics() {
            return new GCMetric();
        }
    }

    指标获取类

    public class GCProvider {
    
        private GCMetricAccessor metricAccessor;
        private List<GarbageCollectorMXBean> beans;
    
        public GCProvider() {
            // 获得 GarbageCollectorMXBean 数组。
            beans = ManagementFactory.getGarbageCollectorMXBeans();
            // 找到 GC 算法,创建对应的 GCMetricAccessor 对象。
            for (GarbageCollectorMXBean bean : beans) {
                String name = bean.getName();
                GCMetricAccessor accessor = findByBeanName(name);
                if (accessor != null) {
                    metricAccessor = accessor;
                    break;
                }
            }
            // 找不到 GC 算法,创建 UnknowGC 对象。
            if (metricAccessor == null) {
                this.metricAccessor = new UnknowGC();
            }
        }
    
        public GCMetric getGCMetrics() {
            return metricAccessor.getGCMetrics();
        }
    
        private GCMetricAccessor findByBeanName(String name) {
            if (name.indexOf("PS") > -1) {
                //Parallel (Old) collector ( -XX:+UseParallelOldGC )
                return new ParallelGCModule(beans);
            } else if (name.indexOf("ConcurrentMarkSweep") > -1) {
                // CMS collector ( -XX:+UseConcMarkSweepGC )
                return new CMSGCModule(beans);
            } else if (name.indexOf("G1") > -1) {
                // G1 collector ( -XX:+UseG1GC )
                return new G1GCModule(beans);
            } else if ("MarkSweepCompact".equals(name)) {
                // Serial collector ( -XX:+UseSerialGC )
                return new SerialGCModule(beans);
            } else {
                // Unknown
                return null;
            }
        }
    }

    各种指标获取类

    @NoArgsConstructor
    public class JvmMetricsFetcher {
    
        private Logger logger = LoggerFactory.getLogger(getClass());
        
        private static final String METRIC_NAME_APP_INSTANCE_JVM_MEM = "jvm-mem";
        private static final String METRIC_NAME_APP_INSTANCE_JVM_GC = "jvm-gc";
        
        private static final String METRIC_FIELD_NAME_FULLGCCOUNT = "fullGCCount";
        private static final String METRIC_FIELD_NAME_FULLGCTIME = "fullGCTime";
        private static final String METRIC_FIELD_NAME_MINORGCCOUNT = "minorGCCount";
        private static final String METRIC_FIELD_NAME_MINORGCTIME = "minorGCTime";
        
        private static final String METRIC_FIELD_NAME_HEAPMAX = "heapMax";
        private static final String METRIC_FIELD_NAME_HEAPUSED = "heapUsed";
        private static final String METRIC_FIELD_NAME_HEAPALLOCATED = "heapAllocated";
        private static final String METRIC_FIELD_NAME_NONHEAPMAX = "nonHeapMax";
        private static final String METRIC_FIELD_NAME_NONHEAPUSED = "nonHeapUsed";
        private static final String METRIC_FIELD_NAME_NONHEAPALLOCATED = "nonHeapAllocated";
        private static final String METRIC_FIELD_NAME_PERMGENMAX = "permGenMax";
        private static final String METRIC_FIELD_NAME_PERMGENUSED = "permGenUsed";
        private static final String METRIC_FIELD_NAME_PERMGENALLOCATED = "permGenAllocated";
        private static final String METRIC_FIELD_NAME_CODECACHEMAX = "codeCacheMax";
        private static final String METRIC_FIELD_NAME_CODECACHEUSED = "codeCacheUsed";
        private static final String METRIC_FIELD_NAME_CODECACHEALLOCATED = "codeCacheAllocated";
        private static final String METRIC_FIELD_NAME_EDENMAX = "edenMax";
        private static final String METRIC_FIELD_NAME_EDENUSED = "edenUsed";
        private static final String METRIC_FIELD_NAME_EDENALLOCATED = "edenAllocated";
        private static final String METRIC_FIELD_NAME_OLDMAX = "oldMax";
        private static final String METRIC_FIELD_NAME_OLDUSED = "oldUsed";
        private static final String METRIC_FIELD_NAME_OLDALLOCATED = "oldAllocated";
        private static final String METRIC_FIELD_NAME_SURVIVORMAX = "survivorMax";
        private static final String METRIC_FIELD_NAME_SURVIVORUSED = "survivorUsed";
        private static final String METRIC_FIELD_NAME_SURVIVORALLOCATED = "survivorAllocated";
        private static final String METRIC_FIELD_NAME_METASPACEMAX = "metaspaceMax";
        private static final String METRIC_FIELD_NAME_METASPACEUSED = "metaspaceUsed";
        private static final String METRIC_FIELD_NAME_METASPACEALLOCATED = "metaspaceAllocated";
        
        private static final String METRIC_FIELD_NAME_LOADEDCLASSES = "loadedClasses";
        private static final String METRIC_FIELD_NAME_TOTALLOADEDCLASSES = "totalLoadedClasses";
        private static final String METRIC_FIELD_NAME_UNLOADEDCLASSES = "unloadedClasses";
        
        private static final String METRIC_FIELD_NAME_TOTALTHREADS = "totalThreads";
        private static final String METRIC_FIELD_NAME_LIVINGTHREADS = "livingThreads";
        private static final String METRIC_FIELD_NAME_PEAKTHREADS = "peakThreads";
        private static final String METRIC_FIELD_NAME_DAEMONTHREAD = "daemonThread";
        
        @Value("${wdgm.monitor.jvm.metrics.fetch.intervalMS:5000}")
        private int fetchingExecutingInterval;
        @Value("${wdgm.monitor.jvm.metrics.output.intervalMS:10000}")
        private int outputingExecutingInterval;
        
        @Autowired
        private IMonitorDataOutputer metricOutputer;
        @Autowired
        private ClassLoadingProvider classLoadingProvider;
        @Autowired
        private GCProvider gcProvider;
        @Autowired
        private MemoryProvider memoryProvider;
        @Autowired
        private ThreadProvider threadProvider;
        
        private Queue<MonitorDataItem> metricCache;
        private Queue<MonitorDataItem> metricCacheBck;
        private Lock cacheOpLock = new ReentrantLock();
        
        private ScheduledExecutorService executorForFetching;
        private ScheduledExecutorService executorForOutputing;
        
        @PostConstruct
        public void init(){
            this.metricCache = new LinkedBlockingDeque<>();
            this.metricCacheBck = new LinkedBlockingDeque<>();
            
            // 启动线程
            this.executorForFetching = Executors.newScheduledThreadPool(1);
            this.executorForOutputing = Executors.newScheduledThreadPool(1);
            this.executorForFetching.scheduleAtFixedRate(new FetchingThread(), 
                    5000, 
                    this.fetchingExecutingInterval, 
                    TimeUnit.MILLISECONDS);
            this.executorForOutputing.scheduleAtFixedRate(new OutputThread(), 
                    5000, 
                    this.outputingExecutingInterval, 
                    TimeUnit.MILLISECONDS);
        }
        
        @PreDestroy
        public void destroy(){
            // 关闭线程
            this.executorForFetching.shutdown();
            this.executorForOutputing.shutdown();
        }
        
        class FetchingThread implements Runnable{
    
            @Override
            public void run() {
                try{
                    // 采集JVM指标
                    ClassLoadingMetric classLoadingMetrics = classLoadingProvider.getClassLoadingMetrics();
                    JvmMemoryMetric jvmMemoryMetrics = memoryProvider.getJvmMemoryMetrics();
                    ThreadMetric threadMetrics = threadProvider.getClassLoadingMetrics();
                    MonitorDataItem jvmMetricsItem = MonitorDataItem.metricItem()
                            .withMetricName(METRIC_NAME_APP_INSTANCE_JVM_MEM)
                            .withMetricField(METRIC_FIELD_NAME_LOADEDCLASSES, classLoadingMetrics.getLoadedClasses())
                            .withMetricField(METRIC_FIELD_NAME_TOTALLOADEDCLASSES, classLoadingMetrics.getTotalLoadedClasses())
                            .withMetricField(METRIC_FIELD_NAME_UNLOADEDCLASSES, classLoadingMetrics.getUnloadedClasses())
                            
                            .withMetricField(METRIC_FIELD_NAME_CODECACHEALLOCATED, NumConvertUtil.byteToM(jvmMemoryMetrics.getCodeCacheAllocated()))
                            .withMetricField(METRIC_FIELD_NAME_CODECACHEMAX, NumConvertUtil.byteToM(jvmMemoryMetrics.getCodeCacheMax()))
                            .withMetricField(METRIC_FIELD_NAME_CODECACHEUSED, NumConvertUtil.byteToM(jvmMemoryMetrics.getCodeCacheUsed()))
                            .withMetricField(METRIC_FIELD_NAME_EDENALLOCATED, NumConvertUtil.byteToM(jvmMemoryMetrics.getEdenAllocated()))
                            .withMetricField(METRIC_FIELD_NAME_EDENMAX, NumConvertUtil.byteToM(jvmMemoryMetrics.getEdenMax()))
                            .withMetricField(METRIC_FIELD_NAME_EDENUSED, NumConvertUtil.byteToM(jvmMemoryMetrics.getEdenUsed()))
                            .withMetricField(METRIC_FIELD_NAME_HEAPALLOCATED, NumConvertUtil.byteToM(jvmMemoryMetrics.getHeapAllocated()))
                            .withMetricField(METRIC_FIELD_NAME_HEAPMAX, NumConvertUtil.byteToM(jvmMemoryMetrics.getHeapMax()))
                            .withMetricField(METRIC_FIELD_NAME_HEAPUSED, NumConvertUtil.byteToM(jvmMemoryMetrics.getHeapUsed()))
                            .withMetricField(METRIC_FIELD_NAME_METASPACEALLOCATED, NumConvertUtil.byteToM(jvmMemoryMetrics.getMetaspaceAllocated()))
                            .withMetricField(METRIC_FIELD_NAME_METASPACEMAX, NumConvertUtil.byteToM(jvmMemoryMetrics.getMetaspaceMax()))
                            .withMetricField(METRIC_FIELD_NAME_METASPACEUSED, NumConvertUtil.byteToM(jvmMemoryMetrics.getMetaspaceUsed()))
                            .withMetricField(METRIC_FIELD_NAME_NONHEAPALLOCATED, NumConvertUtil.byteToM(jvmMemoryMetrics.getNonHeapAllocated()))
                            .withMetricField(METRIC_FIELD_NAME_NONHEAPMAX, NumConvertUtil.byteToM(jvmMemoryMetrics.getNonHeapMax()))
                            .withMetricField(METRIC_FIELD_NAME_NONHEAPUSED, NumConvertUtil.byteToM(jvmMemoryMetrics.getNonHeapUsed()))
                            .withMetricField(METRIC_FIELD_NAME_OLDALLOCATED, NumConvertUtil.byteToM(jvmMemoryMetrics.getOldAllocated()))
                            .withMetricField(METRIC_FIELD_NAME_OLDMAX, NumConvertUtil.byteToM(jvmMemoryMetrics.getOldMax()))
                            .withMetricField(METRIC_FIELD_NAME_OLDUSED, NumConvertUtil.byteToM(jvmMemoryMetrics.getOldUsed()))
                            .withMetricField(METRIC_FIELD_NAME_PERMGENALLOCATED, NumConvertUtil.byteToM(jvmMemoryMetrics.getPermGenAllocated()))
                            .withMetricField(METRIC_FIELD_NAME_PERMGENMAX, NumConvertUtil.byteToM(jvmMemoryMetrics.getPermGenMax()))
                            .withMetricField(METRIC_FIELD_NAME_PERMGENUSED, NumConvertUtil.byteToM(jvmMemoryMetrics.getPermGenUsed()))
                            .withMetricField(METRIC_FIELD_NAME_SURVIVORALLOCATED, NumConvertUtil.byteToM(jvmMemoryMetrics.getSurvivorAllocated()))
                            .withMetricField(METRIC_FIELD_NAME_SURVIVORMAX, NumConvertUtil.byteToM(jvmMemoryMetrics.getSurvivorMax()))
                            .withMetricField(METRIC_FIELD_NAME_SURVIVORUSED, NumConvertUtil.byteToM(jvmMemoryMetrics.getSurvivorUsed()))
                            
                            .withMetricField(METRIC_FIELD_NAME_DAEMONTHREAD, threadMetrics.getDaemonThreads())
                            .withMetricField(METRIC_FIELD_NAME_LIVINGTHREADS, threadMetrics.getLivingThreads())
                            .withMetricField(METRIC_FIELD_NAME_PEAKTHREADS, threadMetrics.getPeakThreads())
                            .withMetricField(METRIC_FIELD_NAME_TOTALTHREADS, threadMetrics.getTotalThreads())
                            .build();
                    // 采集JVM GC指标
                    GCMetric gcMetrics = gcProvider.getGCMetrics();
                    MonitorDataItem gcMetricsItem = MonitorDataItem.metricItem()
                            .withMetricName(METRIC_NAME_APP_INSTANCE_JVM_GC)
                            .withMetricField(METRIC_FIELD_NAME_FULLGCCOUNT, gcMetrics.getFullGCCount())
                            .withMetricField(METRIC_FIELD_NAME_FULLGCTIME, gcMetrics.getFullGCTime())
                            .withMetricField(METRIC_FIELD_NAME_MINORGCCOUNT, gcMetrics.getMinorGCCount())
                            .withMetricField(METRIC_FIELD_NAME_MINORGCTIME, gcMetrics.getMinorGCTime())
                            .build();
                    
                    try{
                        cacheOpLock.lock();
                        metricCache.offer(gcMetricsItem);
                        metricCache.offer(jvmMetricsItem);
                    } finally{
                        cacheOpLock.unlock();
                    }
                } catch(Exception e){
                    logger.error("获取Jvm指标数据失败:", e);
                }
            }
            
        }
        
        class OutputThread implements Runnable{
    
            @Override
            public void run() {
                try{
                
                    try{
                        cacheOpLock.lock();
                        
                        Queue<MonitorDataItem> q = metricCache;
                        metricCache = metricCacheBck;
                        metricCacheBck = q;
                        
                    } finally{
                        cacheOpLock.unlock();
                    }
                    
                    if(!metricCacheBck.isEmpty()){
                        List<MonitorDataItem> metricItems = new ArrayList<>();
                        for(int i = 0; i < metricCacheBck.size(); i++){
                            metricItems.add(metricCacheBck.poll());
                        }
                        metricOutputer.output(metricItems);
                    }
                } catch(Exception e){
                    logger.error("输出Jvm指标数据失败:", e);
                }
            }
            
        }
    }

    。。。

  • 相关阅读:
    android EditText 软键盘 一些总结
    Activity的4种加载模式最佳解答及Intent常用标识
    Android App监听软键盘按键的三种方式
    解决ScrollView下嵌套ListView、GridView显示不全的问题(冲突)
    Android使用WindowManager实现悬浮窗口
    android 设置软键盘默认为26位软键盘
    android:configChanges属性总结
    空腹吃香蕉对身体好吗?哪些水果不宜空腹吃
    冒泡排序,选择排序,二分法
    Android:内存优化的一些总结
  • 原文地址:https://www.cnblogs.com/suntp/p/12214639.html
Copyright © 2011-2022 走看看