Rag*_*ani 5 java garbage-collection jmx mxbean
我正在编写一个Java应用程序,我使用Java GarbageCollectorMXBeanAPI定期(每5秒)获取一次收集计数.以下是我为完成任务而编写的程序.
import java.io.IOException;
import java.lang.management.GarbageCollectorMXBean;
import java.lang.management.ManagementFactory;
import java.util.HashMap;
import java.util.Map;
import javax.management.MBeanServerConnection;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
public class JMXTest {
public static final String GC_NAME = "java.lang:name=MarkSweepCompact,type=GarbageCollector";
private static GarbageCollectorMXBean garbageCollectorMXBean;
private static JMXConnector jmxConnector;
private static MBeanServerConnection mbsc;
public static void main(String[] args) throws Exception {
String rmiHostname = "jmxserver";
String defaultUrl = "service:jmx:rmi:///jndi/rmi://" + rmiHostname + ":1999/jmxrmi";
JMXServiceURL jmxServiceURL = new JMXServiceURL(defaultUrl);
Map<String,Object> jmxCredentials = new HashMap<String,Object>();
String[] credentials = new String[]{"jmxusername", "jmxpassword"};
jmxCredentials.put("jmx.remote.credentials", credentials);
boolean run = true;
while(run){
try {
if(garbageCollectorMXBean == null){
if (mbsc == null){
jmxConnector = JMXConnectorFactory.connect(jmxServiceURL, jmxCredentials);
mbsc = jmxConnector.getMBeanServerConnection();
}
garbageCollectorMXBean = ManagementFactory.newPlatformMXBeanProxy(mbsc, GC_NAME,GarbageCollectorMXBean.class);
}
long count = garbageCollectorMXBean.getCollectionCount();
System.out.println("Garbage Collector count = " + count);
} catch (Exception e) {
e.printStackTrace();
garbageCollectorMXBean = null;
if (jmxConnector != null)
{
try
{
jmxConnector.close();
} catch (IOException ioe) {}
jmxConnector = null;
}
mbsc = null;
}
Thread.currentThread().sleep(5000);
}
}
Run Code Online (Sandbox Code Playgroud)
}
程序运行正常,但有时它会在每个循环中重复开始提供以下IOException.
Exception in thread "main" java.io.IOException: The client has been closed.
at java.util.TimerThread.run(Timer.java:505)
at com.sun.jmx.remote.internal.ClientCommunicatorAdmin.restart(ClientCommunicatorAdmin.java:94)
at com.sun.jmx.remote.internal.ClientCommunicatorAdmin.gotIOException(ClientCommunicatorAdmin.java:54)
at javax.management.remote.rmi.RMIConnector$RMIClientCommunicatorAdmin.gotIOException(RMIConnector.java:1470)
at javax.management.remote.rmi.RMIConnector$RemoteMBeanServerConnection.getAttribute(RMIConnector.java:906)
at com.ibm.lang.management.OpenTypeMappingIHandler$6.run(OpenTypeMappingIHandler.java:506)
at java.security.AccessController.doPrivileged(AccessController.java:330)
at com.ibm.lang.management.OpenTypeMappingIHandler.invokeAttributeGetter(OpenTypeMappingIHandler.java:501)
at com.ibm.lang.management.OpenTypeMappingIHandler.invoke(OpenTypeMappingIHandler.java:121)
at com.sun.proxy.$Proxy112.getCollectionCount(Unknown Source)
at JMXTest.main(JMXTest.java:48)
Run Code Online (Sandbox Code Playgroud)
查看代码,将在catch块中捕获任何异常,其中所有字段将初始化为null,并且在下一个循环中将重新初始化所有字段.但是,查看日志,一旦异常开始,我只能getCollectionCount()在每个循环中调用异常.我想知道即使对象被重新初始化,每次我得到相同的异常.
我正在从以上信息中寻找以下内容
java.io.IOException: The client has been closed.在上面的场景中得到了这个例外.我知道,如果我们调用jmxConnector.close()然后使用已创建的garbageCollectorMXBean对象来获取集合计数,我们就会得到这个.但我的代码并没有遵循这条道路.jmxserver远程JMX服务器有贡献吗?我试图通过停止/重新启动远程JMX服务器来重现,但无法做到.小智 0
从堆栈跟踪的最后一行来看:
at com.sun.proxy.$Proxy112.getCollectionCount(Unknown Source)
at JMXTest.main(JMXTest.java:48)
Run Code Online (Sandbox Code Playgroud)
看来问题出在代码行上
if (jmxConnector != null)
{
try
{
jmxConnector.close();
} catch (IOException ioe) {}
jmxConnector = null; //...line no.48
}
mbsc = null; //......this is probably causing the issue
Run Code Online (Sandbox Code Playgroud)
@raghavendra,当您从“JMXConnector”获取“MBeanServerConnection”对象时,您应该按顺序关闭对象/使它们无效,即将代码更改为
if (jmxConnector != null)
{
try
{
mbsc = null; //...object handle assigned null before closing the connector
jmxConnector.close();
} catch (IOException ioe) {}
jmxConnector = null;
}
Run Code Online (Sandbox Code Playgroud)