前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >获取当前jvm数据

获取当前jvm数据

作者头像
JQ实验室
发布2022-02-14 20:56:18
1.7K0
发布2022-02-14 20:56:18
举报
文章被收录于专栏:实用技术实用技术
代码语言:javascript
复制
获取当前jvm数据
代码语言:javascript
复制
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.lang.management.ManagementFactory;

import org.apache.log4j.Logger;

import com.sun.management.OperatingSystemMXBean;

public class MonitorUtil {
    private static final Logger logger = Logger.getLogger(MonitorUtil.class);
    //可以设置长些,防止读到运行此次系统检查时的cpu占用率,就不准了  
    private static final int CPUTIME = 5000;  
  
    private static final int PERCENT = 100;  
  
    private static final int FAULTLENGTH = 10;  
  
    /** *//** 
     * 获得当前的监控对象. 
     */  
    public static String getMonitorInfoBean() throws Exception {  
        int kb = 1024;  
          
        // 可使用内存  
        long totalMemory = Runtime.getRuntime().totalMemory() / kb;  
        // 剩余内存  
        long freeMemory = Runtime.getRuntime().freeMemory() / kb;  
        // 最大可使用内存  
        long maxMemory = Runtime.getRuntime().maxMemory() / kb;  
  
        OperatingSystemMXBean osmxb = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();  
  
        // 操作系统  
        String osName = System.getProperty("os.name");  
        // 总的物理内存  
        long totalMemorySize = osmxb.getTotalPhysicalMemorySize() / kb;  
        // 剩余的物理内存  
        long freePhysicalMemorySize = osmxb.getFreePhysicalMemorySize() / kb;  
        // 已使用的物理内存  
        long usedMemory = (osmxb.getTotalPhysicalMemorySize() - osmxb  
                .getFreePhysicalMemorySize())  
                / kb;  
  
        // 获得线程总数  
        ThreadGroup parentThread;  
        for (parentThread = Thread.currentThread().getThreadGroup(); parentThread  
                .getParent() != null; parentThread = parentThread.getParent())  
            ;  
        int totalThread = parentThread.activeCount();  
  
        double cpuRatio = 0;  
        if (osName.toLowerCase().startsWith("windows")) {  
            cpuRatio = getCpuRatioForWindows();  
        }  
          
        StringBuffer sb = new StringBuffer();
        double total = (Runtime.getRuntime().totalMemory()) / (1024.0 * 1024);
        double max = (Runtime.getRuntime().maxMemory()) / (1024.0 * 1024);
        double free = (Runtime.getRuntime().freeMemory()) / (1024.0 * 1024);
        logger.info("Java 虚拟机试图使用的最大内存量(当前JVM的最大可用内存) maxMemory(): " + max + "MB<br/>");
        logger.info("Java 虚拟机中的内存总量(当前JVM占用的内存总数) totalMemory(): " + total + "MB<br/>");
        logger.info("Java 虚拟机中的空闲内存量(当前JVM空闲内存) freeMemory(): " + free + "MB<br/>");
        logger.info("因为JVM只有在需要内存时才占用物理内存使用,所以freeMemory()的值一般情况下都很小,<br/>" +
        "而JVM实际可用内存并不等于freeMemory(),而应该等于 maxMemory() - totalMemory() + freeMemory()。<br/>");
        logger.info("JVM实际可用内存: " + (max - total + free) + "MB<br/>");
        logger.info("cpu占有率=" + cpuRatio+"/n");
        logger.info("可使用内存=" + totalMemory+"/n");  
        logger.info("剩余内存=" + freeMemory+"/n");  
        logger.info("最大可使用内存=" + maxMemory+"/n");  
          
        logger.info("操作系统=" + osName+"/n");  
        logger.info("总的物理内存=" + totalMemorySize + "kb/n");  
        logger.info("剩余的物理内存=" + freeMemory + "kb/n");  
        logger.info("已使用的物理内存=" + usedMemory + "kb/n");  
        logger.info("线程总数=" + totalThread+ "/n");  
        return sb.toString();  
    }  
  
    /** *//** 
     * 获得CPU使用率. 
     */  
    private static double getCpuRatioForWindows() {  
        try {  
            String procCmd = System.getenv("windir")  
                    + "\\system32\\wbem\\wmic.exe process get Caption,CommandLine,"  
                    + "KernelModeTime,ReadOperationCount,ThreadCount,UserModeTime,WriteOperationCount";  
            // 取进程信息  
            long[] c0 = readCpu(Runtime.getRuntime().exec(procCmd));  
            Thread.sleep(CPUTIME);  
            long[] c1 = readCpu(Runtime.getRuntime().exec(procCmd));  
            if (c0 != null && c1 != null) {  
                long idletime = c1[0] - c0[0];  
                long busytime = c1[1] - c0[1];  
                return Double.valueOf(  
                        PERCENT * (busytime) / (busytime + idletime))  
                        .doubleValue();  
            } else {  
                return 0.0;  
            }  
        } catch (Exception ex) {  
            ex.printStackTrace();  
            return 0.0;  
        }  
    }  
  
    /** *//** 
     * 读取CPU信息. 
   */  
    private static long[] readCpu(final Process proc) {  
        long[] retn = new long[2];  
        try {  
            proc.getOutputStream().close();  
            InputStreamReader ir = new InputStreamReader(proc.getInputStream());  
            LineNumberReader input = new LineNumberReader(ir);  
            String line = input.readLine();  
            if (line == null || line.length() < FAULTLENGTH) {  
                return null;  
            }  
            int capidx = line.indexOf("Caption");  
            int cmdidx = line.indexOf("CommandLine");  
            int rocidx = line.indexOf("ReadOperationCount");  
            int umtidx = line.indexOf("UserModeTime");  
            int kmtidx = line.indexOf("KernelModeTime");  
            int wocidx = line.indexOf("WriteOperationCount");  
            long idletime = 0;  
            long kneltime = 0;  
            long usertime = 0;  
            while ((line = input.readLine()) != null) {  
                if (line.length() < wocidx) {  
                    continue;  
                }  
                // 字段出现顺序:Caption,CommandLine,KernelModeTime,ReadOperationCount,  
                // ThreadCount,UserModeTime,WriteOperation  
                String caption = substring(line, capidx, cmdidx - 1)  
                        .trim();  
                String cmd = substring(line, cmdidx, kmtidx - 1).trim();  
                if (cmd.indexOf("wmic.exe") >= 0) {  
                    continue;  
                }  
                // log.info("line="+line);  
                if (caption.equals("System Idle Process")  
                        || caption.equals("System")) {  
                    idletime += Long.valueOf(  
                            substring(line, kmtidx, rocidx - 1).trim())  
                            .longValue();  
                    idletime += Long.valueOf(  
                            substring(line, umtidx, wocidx - 1).trim())  
                            .longValue();  
                    continue;  
                }  
  
                kneltime += Long.valueOf(  
                        substring(line, kmtidx, rocidx - 1).trim())  
                        .longValue();  
                usertime += Long.valueOf(  
                        substring(line, umtidx, wocidx - 1).trim())  
                        .longValue();  
            }  
            retn[0] = idletime;  
            retn[1] = kneltime + usertime;  
            return retn;  
        } catch (Exception ex) {  
            ex.printStackTrace();  
        } finally {  
            try {  
                proc.getInputStream().close();  
            } catch (Exception e) {  
                e.printStackTrace();  
            }  
        }  
        return null;  
    }  
        /** *//** 
         * 由于String.subString对汉字处理存在问题: 
         * @param src 要截取的字符串 
         * @param start_idx 开始坐标(包括该坐标) 
         * @param end_idx   截止坐标(包括该坐标) 
         * @return 
         */  
        public static String substring(String src, int start_idx, int end_idx){  
            byte[] b = src.getBytes();  
            String tgt = "";  
            for(int i=start_idx; i<=end_idx; i++){  
                tgt +=(char)b[i];  
            }  
            return tgt;  
        }  
   }
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-09-07 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档