org.gridkit.jvmtool.gcflow.GcAdapter Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of gcflow Show documentation
Show all versions of gcflow Show documentation
MBean to JSON dump command for Swiss Java Knife (SJK) tool
package org.gridkit.jvmtool.gcflow;
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import javax.management.JMX;
import javax.management.MBeanServerConnection;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import org.gridkit.jvmtool.gcflow.GarbageCollectionSampler.GcReport;
import org.gridkit.jvmtool.gcflow.GcKnowledgeBase.PoolType;
import com.sun.management.GarbageCollectorMXBean;
import com.sun.management.GcInfo;
@SuppressWarnings("restriction")
class GcAdapter {
private final GarbageCollectionSampler sampler;
private final GarbageCollectorMXBean gc;
private final String name;
private final long processStartMs;
private final List collectedPools;
private final List allCollectedPools;
private final List edenPools;
private final List survivourPools;
private final List youngPools;
private final List oldPools;
private final List permPools;
private final boolean isYoung;
private final boolean isConcurent;
private long gcCount = -1;
private long prevCollectionEndTime = -1;
public GcAdapter(MBeanServerConnection mserver, ObjectName gcname, GarbageCollectionSampler sampler) throws IOException, MalformedObjectNameException {
this.sampler = sampler;
gc = JMX.newMXBeanProxy(mserver, gcname, GarbageCollectorMXBean.class);
name = gc.getName();
RuntimeMXBean runtime = JMX.newMXBeanProxy(mserver, new ObjectName(ManagementFactory.RUNTIME_MXBEAN_NAME), RuntimeMXBean.class);
processStartMs = runtime.getStartTime();
collectedPools = Arrays.asList(gc.getMemoryPoolNames());
allCollectedPools = new ArrayList(GcKnowledgeBase.allCollectedPools(mserver));
Map> types = GcKnowledgeBase.classifyMemoryPools(mserver);
edenPools = getMemPools(types, PoolType.EDEN);
survivourPools = getMemPools(types, PoolType.SURVIVOR);
oldPools = getMemPools(types, PoolType.TENURED);
permPools = getMemPools(types, PoolType.PERMANENT);
youngPools = new ArrayList();
youngPools.addAll(edenPools);
youngPools.addAll(survivourPools);
isYoung = collectedPools.containsAll(oldPools);
isConcurent = "ConcurrentMarkSweep".equals(name);
}
private List getMemPools(Map> types, PoolType type) {
List pools;
if (types.containsKey(type)) {
pools = new ArrayList(types.get(type));
}
else {
pools = Collections.emptyList();
}
return pools;
}
public void report() {
try {
GcInfo lastGc = gc.getLastGcInfo();
if (lastGc == null || lastGc.getId() == gcCount) {
return;
}
else {
int missed = (int)(lastGc.getId() - 1 - gcCount);
if (gcCount < 0) {
missed = 0;
}
long gcInterval = lastGc.getStartTime() - prevCollectionEndTime;
prevCollectionEndTime = lastGc.getEndTime();
if (gcCount < 0) {
gcInterval = -1;
}
if (lastGc.getEndTime() == 0) {
// no GC so far
prevCollectionEndTime = 0;
gcCount = lastGc.getId();
}
else {
gcCount = lastGc.getId();
sampler.report(name, missed, new Report(lastGc, gcInterval));
}
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private class Report implements GcReport {
private GcInfo gcInfo;
private long gcInterval;
public Report(GcInfo gcInfo, long gcInterval) {
this.gcInfo = gcInfo;
this.gcInterval = gcInterval;
}
@Override
public long getId() {
return gcInfo.getId();
}
@Override
public long getWallClockStartTime() {
return processStartMs + gcInfo.getStartTime();
}
@Override
public long getWallClockEndTime() {
return processStartMs + gcInfo.getEndTime();
}
@Override
public long getJvmClockStartTime() {
return gcInfo.getStartTime();
}
@Override
public long getJvmClockEndTime() {
return gcInfo.getEndTime();
}
@Override
public long getDuration() {
return gcInfo.getDuration();
}
@Override
public long getTimeSincePreviousGC() {
return gcInterval;
}
@Override
public boolean isYoungGC() {
return isYoung;
}
@Override
public boolean isConcurrentGC() {
return isConcurent;
}
@Override
public long getCollectedSize() {
return getTotalSizeBefore() - getTotalSizeAfter();
}
@Override
public long getPromotedSize() {
return getSizeAfter(oldPools) - getSizeBefore(oldPools);
}
@Override
public long getTotalSizeBefore() {
return getSizeBefore(allCollectedPools);
}
@Override
public long getTotalSizeAfter() {
return getSizeAfter(allCollectedPools);
}
@Override
public Collection getColletedPools() {
return Collections.unmodifiableCollection(collectedPools);
}
@Override
public Collection getAllCollectedPools() {
return Collections.unmodifiableCollection(allCollectedPools);
}
@Override
public Collection getAllMemoryPools() {
return Collections.unmodifiableCollection(gcInfo.getMemoryUsageAfterGc().keySet());
}
@Override
public long getSizeBefore(String pool) {
return gcInfo.getMemoryUsageBeforeGc().get(pool).getUsed();
}
@Override
public long getSizeAfter(String pool) {
return gcInfo.getMemoryUsageAfterGc().get(pool).getUsed();
}
@Override
public long getSizeBefore(Collection pools) {
long total = 0;
for(String pool: pools) {
total += getSizeBefore(pool);
}
return total;
}
@Override
public long getSizeAfter(Collection pools) {
long total = 0;
for(String pool: pools) {
total += getSizeAfter(pool);
}
return total;
}
@Override
public Collection getEdenPools() {
List list = new ArrayList(edenPools);
list.retainAll(gcInfo.getMemoryUsageAfterGc().keySet());
return list;
}
@Override
public Collection getSurvivourPools() {
List list = new ArrayList(survivourPools);
list.retainAll(gcInfo.getMemoryUsageAfterGc().keySet());
return list;
}
@Override
public Collection getOldSpacePools() {
List list = new ArrayList(oldPools);
list.retainAll(gcInfo.getMemoryUsageAfterGc().keySet());
return list;
}
@Override
public Collection getPermSpacePools() {
List list = new ArrayList(permPools);
list.retainAll(gcInfo.getMemoryUsageAfterGc().keySet());
return list;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy