Java堆大小监视器解决方案

时间:2019-01-21 14:28:03

标签: java size heap monitoring

我想监视服务器期间在Windows上运行的jboss服务的已用Java堆大小。我首先尝试从Windows使用perfmon,但没有得到我期望的值。我可以使用jmx(server:port)将jvisualvm挂接到此服务,也可以使用jconsole或jmc(java任务控制)。实际上,由于jvm版本,我无法使用飞行记录。 使用jcmd或jstat时,看不到我感兴趣的过程。由于我是Java新手,有人可以建议一个应用程序或脚本来让我掌握这些值并将其推送到例如文本文件中。如果有一个库,我也可以在.Net中编写一些代码。

谢谢

2 个答案:

答案 0 :(得分:1)

下面的Java代码将Java堆的使用情况(默认为2分钟)记录到一个文本文件中。您可以根据需要更改代码。根据您的环境更改private String jmxUrl = ...

package com.heap.monitor;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.management.*;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.management.*;
import javax.management.remote.*;

public class HeapMonitor extends Thread {

private JMXServiceURL jmxService = null;
private JMXConnector jmxConnector = null;
protected MBeanServerConnection beanServerConn = null;
private long frequency = 2 * 60 * 1000L; // 2 mins only collects Heap metrics
private String jmxUrl = "service:jmx:rmi:///jndi/rmi://192.168.8.252:12222/jmxrmi";
private String userName = "none";
private String passWord = "none";

public static void main(String[] args) throws InterruptedException {
    HeapMonitor heapMonitor = new HeapMonitor();
    heapMonitor.join();
}

public HeapMonitor() {
    this.start();
}

public void run() {
    boolean flag = true;
    while(flag) {
        try {
            beanServerConn = connectToJVM(jmxUrl, userName, passWord);
            if(beanServerConn!=null) {
                MemoryMXBean mxbean = (MemoryMXBean) ManagementFactory.newPlatformMXBeanProxy(beanServerConn, ManagementFactory.MEMORY_MXBEAN_NAME, MemoryMXBean.class);
                try
                {
                    MemoryUsage heapUsage = mxbean.getHeapMemoryUsage();
                    long used = heapUsage.getUsed();
                    long max = heapUsage.getMax();
                    long commited = heapUsage.getCommitted();
                    long init = heapUsage.getInit();
                    StringBuffer buffer = new StringBuffer();
                    Date date = new Date();
                    buffer.append(date).append(" - ");
                    buffer.append(init).append("   ").append(commited).append("   ").append(max).append("   ").append(used);
                    //System.out.println(buffer.toString());
                    appendStrToFile("heap.txt" , buffer.toString());
                }
                catch(Exception ee) {
                    ee.printStackTrace();
                }
            }
        }
        catch(Exception e) {
            e.printStackTrace();
        }

        try {
            Thread.sleep(frequency);
        }
        catch(Exception e) {
            e.printStackTrace();
        }
    }
}

protected MBeanServerConnection connectToJVM(String jvmURL, String user, String pass)
{
    beanServerConn = null ;  
    try
    {
        jmxService = new JMXServiceURL(jvmURL);
        Map environment = new HashMap();
        int jmxconnect_timeout = 30000;
        environment.put("jmx.remote.x.request.waiting.timeout", Long.toString(jmxconnect_timeout));


        if(user.equalsIgnoreCase("none")|| (pass.equalsIgnoreCase("none"))){
            try{
                jmxConnector = JMXConnectorFactory.connect(jmxService,environment);
                beanServerConn = jmxConnector.getMBeanServerConnection();
            }
            catch(IOException ioe){
            }
        }
        else
        {
            String [] credentials={user,pass};
            environment.put(JMXConnector.CREDENTIALS, credentials);
            try{
                jmxConnector = JMXConnectorFactory.connect(jmxService,environment);
                beanServerConn = jmxConnector.getMBeanServerConnection();

            }
            catch(IOException ioe){
            }
        }

        beanServerConn = jmxConnector.getMBeanServerConnection();

        if(beanServerConn == null)
        {
            System.out.println("Connection to JVM is not established for jvmURL : " + jvmURL);
            closeJVMConn();
        }
    }
    catch(Exception ex)
    {
        System.out.println("Connection to JVM is not established for jvmURL : " + jvmURL);
        closeJVMConn();
    }
    return beanServerConn;
}

public void closeJVMConn(){
    try{
        beanServerConn = null;
        if(jmxConnector != null)
            jmxConnector.close();
    }
    catch(Exception ex){
        return;
    }
}

 public void appendStrToFile(String fileName, String str) { 
    try { 
        // Open given file in append mode. 
        BufferedWriter out = new BufferedWriter(new FileWriter(fileName, true)); 
        out.write(str); 
        out.newLine();
        out.close(); 
    } 
    catch (IOException e) { 
        System.out.println("exception occoured" + e); 
    } 
 } 
}

答案 1 :(得分:0)

使用Jconsole,您可以查看和捕获堆/非堆内存使用情况(以及CPU,线程等)。如截图所示,在Jconsole中,当右键单击“堆内存使用情况图” 时,会出现一个小的弹出窗口。您可以在选定的时间范围内以.csv格式保存数据。

Jconsole Window