Commit d873e5f5 d873e5f5ca1c4cffeb1ab0ad005bac1db000c50f by Christian Gerdes

Ny version som hämtar GC info

Dock räknar den fel på Allocation Rate när heap size minskar från
föregående sampling.
1 parent f95dafd9
javaw.exe -Dcom.sun.management.jmxremote.ssl=false -cp "wls-10.3.6.0.161018.2/wljmxclient.jar;jconsole.1.8.0_91.jar" sun.tools.jconsole.JConsole "service:jmx:rmi:///jndi/iiop://u01891.ef.kap.rsv.se:17020/weblogic.management.mbeanservers.runtime"
\ No newline at end of file
javaw.exe -Dcom.sun.management.jmxremote.ssl=false -cp "wls-10.3.6.0.161018.2/wljmxclient.jar;jconsole.1.8.0_91.jar" sun.tools.jconsole.JConsole "service:jmx:rmi:///jndi/iiop://u02878.ht.kap.rsv.se:17040/weblogic.management.mbeanservers.runtime"
\ No newline at end of file
......@@ -3,15 +3,12 @@ package se.lil.jm;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.HashMap;
import java.util.Set;
import java.util.HashSet;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import javax.management.JMX;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanInfo;
import javax.management.InstanceNotFoundException;
import javax.management.MBeanServerConnection;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
......@@ -26,6 +23,19 @@ public class JmxMon {
String serverName = null;
String runtimeName = null;
int gcType = 0;
public static final int Unknown = 0;
public static final int CMS = 1;
public static final int PS = 2;
public boolean isGCType(int type) {
return (gcType == type);
}
private void setGCType(int type) {
gcType = type;
}
JMXServiceURL url = null;
JMXConnector jmxc = null;
MBeanServerConnection mbsc = null;
......@@ -39,6 +49,19 @@ public class JmxMon {
HashMap<String, LongDelta> longDeltaMap = new HashMap<String, LongDelta>();
HashMap<String, DoubleDelta> doubleDeltaMap = new HashMap<String, DoubleDelta>();
HashSet<String> blocked = new HashSet<String>();
public void dumpDeltas() {
System.out.println("\nLong Deltas:");
for(String key : longDeltaMap.keySet()) {
System.out.println("\"" + key + "\" " + longDeltaMap.get(key).getCurrentValue());
}
System.out.println("\nDouble Deltas:");
for(String key : doubleDeltaMap.keySet()) {
System.out.println("\"" + key + "\" " + doubleDeltaMap.get(key).getCurrentValue());
}
}
private void updateLongDelta (Long timestamp, String name, Long value) {
LongDelta ld = longDeltaMap.get(name);
if(ld == null) {
......@@ -52,6 +75,10 @@ public class JmxMon {
return longDeltaMap.get(name + ":" + attribute);
}
public LongDelta getLongDelta(String key) {
return longDeltaMap.get(key);
}
private void updateDoubleDelta (Long timestamp, String name, Double value) {
DoubleDelta dd = doubleDeltaMap.get(name);
if(dd == null) {
......@@ -65,37 +92,78 @@ public class JmxMon {
return doubleDeltaMap.get(name + ":" + attribute);
}
public DoubleDelta getDoubleDelta(String key) {
return doubleDeltaMap.get(key);
}
private Object getAttributeValue(String name, String attribute) {
Object ro = null;
if(mbsc != null) {
try {
ro = mbsc.getAttribute(new ObjectName(name), attribute);
if(!blocked.contains(name)) ro = mbsc.getAttribute(new ObjectName(name), attribute);
} catch (InstanceNotFoundException ie) {
blocked.add(name);
} catch (Exception e) {
ro = e;
}
}
return ro;
}
private void fetchUpdateAttribute(String name, String attribute) {
String fullName = name + ":" + attribute;
Object obj = getAttributeValue(name, attribute);
Long ts = (Long)getAttributeValue("java.lang:type=Runtime", "Uptime");
if(obj != null) {
if(obj.getClass().equals(java.lang.Long.class)) {
updateLongDelta(ts, fullName, (Long)obj);
String lastKeyName = "";
private void updateCompositeDelta (Long timestamp, String name, CompositeData data) {
for(String key : data.getCompositeType().keySet()) {
String fullName;
if(key.equals("value")) fullName = name + ":" + lastKeyName;
else fullName = name + ":" + key;
Object obj = data.get(key);
updateDelta(timestamp, fullName, obj);
}
if(obj.getClass().equals(java.lang.Integer.class)) {
Integer i = (Integer)obj;
updateLongDelta(ts, fullName, i.longValue());
}
if(obj.getClass().equals(java.lang.Double.class)) {
updateDoubleDelta(ts, fullName, (Double)obj);
private void updateTabularDelta (Long timestamp, String name, TabularData data) {
for(Object obj : data.values()) {
CompositeData cd = (CompositeData)obj;
updateCompositeDelta(timestamp, name, cd);
}
if(obj.getClass().equals(java.lang.Float.class)) {
Float f = (Float)obj;
updateDoubleDelta(ts, fullName, f.doubleValue());
}
private void updateDelta(Long timestamp, String fullName, Object data) {
if(data != null) {
if(data.getClass().equals(java.lang.String.class)) {
lastKeyName = (String)data;
} else
if(data.getClass().equals(java.lang.Long.class)) {
updateLongDelta(timestamp, fullName, (Long)data);
} else
if(data.getClass().equals(java.lang.Integer.class)) {
Integer i = (Integer)data;
updateLongDelta(timestamp, fullName, i.longValue());
} else
if(data.getClass().equals(java.lang.Double.class)) {
updateDoubleDelta(timestamp, fullName, (Double)data);
} else
if(data.getClass().equals(java.lang.Float.class)) {
Float f = (Float)data;
updateDoubleDelta(timestamp, fullName, f.doubleValue());
} else
if(data.getClass().equals(javax.management.openmbean.CompositeDataSupport.class)) {
updateCompositeDelta(timestamp, fullName, (CompositeData)data);
} else
if(data.getClass().equals(javax.management.openmbean.TabularDataSupport.class)) {
updateTabularDelta(timestamp, fullName, (TabularData)data);
} else {
System.out.println("Received Unknown Object: " + data.getClass());
}
}
}
private void fetchUpdateAttribute(String name, String attribute) {
String fullName = name + ":" + attribute;
Object obj = getAttributeValue(name, attribute);
if(obj != null) {
Long ts = (Long)getAttributeValue("java.lang:type=Runtime", "Uptime");
updateDelta(ts, fullName, obj);
}
}
......@@ -204,10 +272,31 @@ public class JmxMon {
fetchUpdateAttribute("java.lang:type=OperatingSystem", "SystemLoadAverage");
fetchUpdateAttribute("java.lang:type=Threading", "ThreadCount");
fetchUpdateAttribute("java.lang:type=ClassLoading", "LoadedClassCount");
fetchUpdateAttribute("java.lang:type=Memory", "HeapMemoryUsage");
// Only get theese if we have the right GC type
if(isGCType(JmxMon.Unknown) || isGCType(JmxMon.PS)) {
fetchUpdateAttribute("java.lang:type=GarbageCollector,name=PS MarkSweep", "LastGcInfo");
fetchUpdateAttribute("java.lang:type=GarbageCollector,name=PS MarkSweep", "CollectionTime");
fetchUpdateAttribute("java.lang:type=GarbageCollector,name=PS Scavenge", "CollectionTime");
fetchUpdateAttribute("java.lang:type=MemoryPool,name=PS Old Gen", "Usage");
}
if(isGCType(JmxMon.Unknown) || isGCType(JmxMon.CMS)) {
fetchUpdateAttribute("java.lang:type=GarbageCollector,name=ConcurrentMarkSweep", "LastGcInfo");
fetchUpdateAttribute("java.lang:type=GarbageCollector,name=ConcurrentMarkSweep", "CollectionTime");
fetchUpdateAttribute("java.lang:type=GarbageCollector,name=ParNew", "CollectionTime");
fetchUpdateAttribute("java.lang:type=MemoryPool,name=CMS Old Gen", "Usage");
}
// Finished updating data
getDataSucess++;
lastFetchTSns = System.nanoTime();
lastRTns = lastFetchTSns - startTSns;
// Check the GC type if not known
if(isGCType(JmxMon.Unknown)) {
if(longDeltaMap.containsKey("java.lang:type=GarbageCollector,name=ConcurrentMarkSweep:CollectionTime")) setGCType(JmxMon.CMS);
if(longDeltaMap.containsKey("java.lang:type=GarbageCollector,name=PS MarkSweep:CollectionTime")) setGCType(JmxMon.PS);
}
return true;
} catch (Throwable e) {
throw (e);
......@@ -276,6 +365,132 @@ public class JmxMon {
return (open/max) * 100D;
}
public double getHeapUsedMB() {
LongDelta ld = getLongDelta("java.lang:type=Memory:HeapMemoryUsage:used");
if(ld != null) {
return (double)ld.getCurrentValue() / (1024D*1024D);
} else {
return 0;
}
}
public double getHeapUsedPercent() {
LongDelta ldu = getLongDelta("java.lang:type=Memory:HeapMemoryUsage:used");
LongDelta ldm = getLongDelta("java.lang:type=Memory:HeapMemoryUsage:max");
if(ldu != null && ldm != null) {
return ((double)ldu.getCurrentValue()/(double)ldm.getCurrentValue()) * 100D;
} else {
return 0;
}
}
public double getHeapAllocationRateMBps() {
LongDelta ldu = getLongDelta("java.lang:type=Memory:HeapMemoryUsage:used");
if(ldu != null) {
if(ldu.getPerSecondValue() > 0) {
return ldu.getPerSecondValue()/(1024D*1024D);
} else {
// negative delta, means we had a major GC in the delta, get the last heap size before GC and add it to the last (previous) value
Long beforeGC = null;
if(isGCType(JmxMon.CMS)) {
LongDelta ld1 = getLongDelta("java.lang:type=GarbageCollector,name=ConcurrentMarkSweep:LastGcInfo:memoryUsageBeforeGc:CMS Old Gen:used");
LongDelta ld2 = getLongDelta("java.lang:type=GarbageCollector,name=ConcurrentMarkSweep:LastGcInfo:memoryUsageBeforeGc:Par Eden Space:used");
LongDelta ld3 = getLongDelta("java.lang:type=GarbageCollector,name=ConcurrentMarkSweep:LastGcInfo:memoryUsageBeforeGc:Par Survivor Space:used");
if(ld1 != null && ld2 != null && ld3 != null)
beforeGC = ld1.getCurrentValue() + ld2.getCurrentValue() + ld3.getCurrentValue();
} else
if(isGCType(JmxMon.PS)) {
LongDelta ld1 = getLongDelta("java.lang:type=GarbageCollector,name=PS MarkSweep:LastGcInfo:memoryUsageBeforeGc:PS Old Gen:used");
LongDelta ld2 = getLongDelta("java.lang:type=GarbageCollector,name=PS MarkSweep:LastGcInfo:memoryUsageBeforeGc:PS Eden Space:used");
LongDelta ld3 = getLongDelta("java.lang:type=GarbageCollector,name=PS MarkSweep:LastGcInfo:memoryUsageBeforeGc:PS Survivor Space:used");
if(ld1 != null && ld2 != null && ld3 != null)
beforeGC = ld1.getCurrentValue() + ld2.getCurrentValue() + ld3.getCurrentValue();
}
if(beforeGC == null) return 0;
if(ldu.lastValue == null) return 0;
ldu.lastValue = beforeGC + ldu.lastValue;
System.out.println("Adjusted heap size with " + beforeGC + " bytes");
return ldu.getPerSecondValue()/(1024D*1024D);
}
} else {
return 0;
}
}
public double getPSOldGenUsedMB() {
LongDelta ld = getLongDelta("java.lang:type=MemoryPool,name=PS Old Gen:Usage:used");
if(ld != null) {
return (double)ld.getCurrentValue() / (1024D*1024D);
} else {
return 0;
}
}
public double getCMSOldGenUsedMB() {
LongDelta ld = getLongDelta("java.lang:type=MemoryPool,name=CMS Old Gen:Usage:used");
if(ld != null) {
return (double)ld.getCurrentValue() / (1024D*1024D);
} else {
return 0;
}
}
public double getPSOldGenUsedPercent() {
LongDelta ldu = getLongDelta("java.lang:type=MemoryPool,name=PS Old Gen:Usage:used");
LongDelta ldm = getLongDelta("java.lang:type=MemoryPool,name=PS Old Gen:Usage:max");
if(ldu != null && ldm != null) {
return ((double)ldu.getCurrentValue()/(double)ldm.getCurrentValue()) * 100D;
} else {
return 0;
}
}
public double getCMSOldGenUsedPercent() {
LongDelta ldu = getLongDelta("java.lang:type=MemoryPool,name=CMS Old Gen:Usage:used");
LongDelta ldm = getLongDelta("java.lang:type=MemoryPool,name=CMS Old Gen:Usage:max");
if(ldu != null && ldm != null) {
return ((double)ldu.getCurrentValue()/(double)ldm.getCurrentValue()) * 100D;
} else {
return 0;
}
}
public double getPSMarkSweepOldGenAfterGCMB() {
LongDelta ld = getLongDelta("java.lang:type=GarbageCollector,name=PS MarkSweep:LastGcInfo:memoryUsageAfterGc:PS Old Gen:used");
if(ld != null) {
return (double)ld.getCurrentValue() / (1024D*1024D);
} else {
return 0;
}
}
public double getCMSMarkSweepOldGenAfterGCMB() {
LongDelta ld = getLongDelta("java.lang:type=GarbageCollector,name=ConcurrentMarkSweep:LastGcInfo:memoryUsageAfterGc:CMS Old Gen:used");
if(ld != null) {
return (double)ld.getCurrentValue() / (1024D*1024D);
} else {
return 0;
}
}
public double getPSMarkSweepPermGenAfterGCMB() {
LongDelta ld = getLongDelta("java.lang:type=GarbageCollector,name=PS MarkSweep:LastGcInfo:memoryUsageAfterGc:PS Perm Gen:used");
if(ld != null) {
return (double)ld.getCurrentValue() / (1024D*1024D);
} else {
return 0;
}
}
public double getCMSMarkSweepPermGenAfterGCMB() {
LongDelta ld = getLongDelta("java.lang:type=GarbageCollector,name=ConcurrentMarkSweep:LastGcInfo:memoryUsageAfterGc:CMS Perm Gen:used");
if(ld != null) {
return (double)ld.getCurrentValue() / (1024D*1024D);
} else {
return 0;
}
}
public JmxMon() {
}
......
......@@ -19,9 +19,12 @@ public class TestRunner {
Long ts1 = System.currentTimeMillis();
JmxMon mon1 = new JmxMon("service:jmx:iiop:///jndi/iiop://u30457:29722/weblogic.management.mbeanservers.runtime"); // 10.3.6.0.161018.2
//JmxMon mon1 = new JmxMon("service:jmx:iiop:///jndi/iiop://u30457:29722/weblogic.management.mbeanservers.runtime"); // 10.3.6.0.161018.2
//JmxMon mon1 = new JmxMon("service:jmx:rmi:///jndi/iiop://u30128:23032/weblogic.management.mbeanservers.runtime"); // 10.3.6.0.161018.2
//JmxMon mon2 = new JmxMon("service:jmx:rmi:///jndi/iiop://u30009:26732/weblogic.management.mbeanservers.runtime"); // 10.3.6.0.12.1
//JmxMon mon1 = new JmxMon("service:jmx:rmi:///jndi/iiop://u02878.ht.kap.rsv.se:17040/weblogic.management.mbeanservers.runtime"); // 10.3.6.0.161018.2 PS
//JmxMon mon1 = new JmxMon("service:jmx:rmi:///jndi/iiop://u01891.ef.kap.rsv.se:17020/weblogic.management.mbeanservers.runtime"); // 10.3.6.0.161018.2 CMS
JmxMon mon1 = new JmxMon("service:jmx:rmi:///jndi/iiop://u30450:34502/weblogic.management.mbeanservers.runtime"); // CMS
mon1.open();
//mon2.open();
jmxList.add(mon1);
......@@ -41,16 +44,33 @@ public class TestRunner {
mon.getData();
time = System.currentTimeMillis() - ts1;
System.out.println(mon.getServerName() + " called in " + time + "ms");
System.out.println(mon.getServerName() + " Process CPU %: " + mon.getCPUPercent());
System.out.println(mon.getServerName() + " Process Threads #: " + mon.getThreads());
System.out.println(mon.getServerName() + " Process Loaded Classes #: " + mon.getLoadedClassCount());
System.out.println(mon.getServerName() + " Process File Descriptors %: " + mon.getSystemFileDescriptorsPercentUsed());
System.out.println(mon.getServerName() + " System Load (per cpu): " + mon.getAverageLoadPerCpu());
System.out.println(mon.getServerName() + " System Load (total): " + mon.getAverageLoad());
System.out.println(mon.getServerName() + " System Memory %: " + mon.getSystemMemoryPercentUsed());
System.out.println(mon.getServerName() + " System Swap %: " + mon.getSystemSwapPercentUsed());
System.out.println(" Process CPU %: " + mon.getCPUPercent());
System.out.println(" Process Threads #: " + mon.getThreads());
System.out.println(" Process Loaded Classes #: " + mon.getLoadedClassCount());
System.out.println(" Process File Descriptors %: " + mon.getSystemFileDescriptorsPercentUsed());
System.out.println(" Process Heap Used %: " + mon.getHeapUsedPercent());
System.out.println(" Process Heap Used MB: " + mon.getHeapUsedMB());
System.out.println(" Allocation Rate MB/s: " + mon.getHeapAllocationRateMBps());
if(mon.isGCType(JmxMon.PS)) {
System.out.println(" PS OldGen Used %: " + mon.getPSOldGenUsedPercent());
System.out.println(" PS OldGen Used MB: " + mon.getPSOldGenUsedMB());
System.out.println(" PS OldGen After Major GC MB: " + mon.getPSMarkSweepOldGenAfterGCMB());
System.out.println(" PS PermGen After Major GC MB: " + mon.getPSMarkSweepPermGenAfterGCMB());
}
if(mon.isGCType(JmxMon.CMS)) {
System.out.println(" CMS OldGen Used %: " + mon.getCMSOldGenUsedPercent());
System.out.println(" CMS OldGen Used MB: " + mon.getCMSOldGenUsedMB());
System.out.println(" CMS OldGen After Major GC MB: " + mon.getCMSMarkSweepOldGenAfterGCMB());
System.out.println("CMS PermGen After Major GC MB: " + mon.getCMSMarkSweepPermGenAfterGCMB());
}
System.out.println(" System Load (per cpu): " + mon.getAverageLoadPerCpu());
System.out.println(" System Load (total): " + mon.getAverageLoad());
System.out.println(" System Memory %: " + mon.getSystemMemoryPercentUsed());
System.out.println(" System Swap %: " + mon.getSystemSwapPercentUsed());
System.out.println();
//mon.dumpDeltas();
}
Thread.sleep(15000);
}
......