序
本文主要研究一下skywalking的GCProvider
GCProvider
skywalking-6.6.0/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/jvm/gc/GCProvider.java
代码语言:javascript复制public enum GCProvider {
INSTANCE;
private GCMetricAccessor metricAccessor;
private List<GarbageCollectorMXBean> beans;
GCProvider() {
beans = ManagementFactory.getGarbageCollectorMXBeans();
for (GarbageCollectorMXBean bean : beans) {
String name = bean.getName();
GCMetricAccessor accessor = findByBeanName(name);
if (accessor != null) {
metricAccessor = accessor;
break;
}
}
if (metricAccessor == null) {
this.metricAccessor = new UnknowGC();
}
}
public List<GC> getGCList() {
return metricAccessor.getGCList();
}
private GCMetricAccessor findByBeanName(String name) {
if (name.indexOf("PS") > -1) {
//Parallel (Old) collector ( -XX: UseParallelOldGC )
return new ParallelGCModule(beans);
} else if (name.indexOf("ConcurrentMarkSweep") > -1) {
// CMS collector ( -XX: UseConcMarkSweepGC )
return new CMSGCModule(beans);
} else if (name.indexOf("G1") > -1) {
// G1 collector ( -XX: UseG1GC )
return new G1GCModule(beans);
} else if (name.equals("MarkSweepCompact")) {
// Serial collector ( -XX: UseSerialGC )
return new SerialGCModule(beans);
} else {
// Unknown
return null;
}
}
}
- GCProvider的构造器通过ManagementFactory.getGarbageCollectorMXBeans()获取GarbageCollectorMXBean列表,之后遍历该列表获取GCMetricAccessor,如果找不到则默认为UnknowGC(
返回空的的NEW、OLD指标
);其getGCList则通过metricAccessor.getGCList()返回GC指标
GCModule
skywalking-6.6.0/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/jvm/gc/GCModule.java
代码语言:javascript复制public abstract class GCModule implements GCMetricAccessor {
private List<GarbageCollectorMXBean> beans;
private long lastOGCCount = 0;
private long lastYGCCount = 0;
private long lastOGCCollectionTime = 0;
private long lastYGCCollectionTime = 0;
public GCModule(List<GarbageCollectorMXBean> beans) {
this.beans = beans;
}
@Override
public List<GC> getGCList() {
List<GC> gcList = new LinkedList<GC>();
for (GarbageCollectorMXBean bean : beans) {
String name = bean.getName();
GCPhrase phrase;
long gcCount = 0;
long gcTime = 0;
if (name.equals(getNewGCName())) {
phrase = GCPhrase.NEW;
long collectionCount = bean.getCollectionCount();
gcCount = collectionCount - lastYGCCount;
lastYGCCount = collectionCount;
long time = bean.getCollectionTime();
gcTime = time - lastYGCCollectionTime;
lastYGCCollectionTime = time;
} else if (name.equals(getOldGCName())) {
phrase = GCPhrase.OLD;
long collectionCount = bean.getCollectionCount();
gcCount = collectionCount - lastOGCCount;
lastOGCCount = collectionCount;
long time = bean.getCollectionTime();
gcTime = time - lastOGCCollectionTime;
lastOGCCollectionTime = time;
} else {
continue;
}
gcList.add(
GC.newBuilder().setPhrase(phrase)
.setCount(gcCount)
.setTime(gcTime)
.build()
);
}
return gcList;
}
protected abstract String getOldGCName();
protected abstract String getNewGCName();
}
- GCModule声明实现了GCMetricAccessor接口,其getGCList方法通过遍历GarbageCollectorMXBean列表计算gcCount、gcTime,并维护lastYGCCount、lastYGCCollectionTime、lastOGCCount、lastOGCCollectionTime指标;由于不同垃圾收集器的NEW、OLD名称不一样,因而这里通过抽象方法暴露给子类去实现,其子类有SerialGCModule、ParallelGCModule、CMSGCModule、G1GCModule
小结
GCProvider的构造器通过ManagementFactory.getGarbageCollectorMXBeans()获取GarbageCollectorMXBean列表,之后遍历该列表获取GCMetricAccessor,如果找不到则默认为UnknowGC(返回空的的NEW、OLD指标
);其getGCList则通过metricAccessor.getGCList()返回GC指标
doc
- GCProvider