未验证 提交 523f4788 编写于 作者: P Peng Junzhi 提交者: GitHub

Remove unnecessary metrics and optimize allocation byte counting (#10738)

上级 ccec8845
...@@ -54,7 +54,7 @@ import java.util.concurrent.atomic.AtomicLong; ...@@ -54,7 +54,7 @@ import java.util.concurrent.atomic.AtomicLong;
public class JvmGcMetrics implements IMetricSet, AutoCloseable { public class JvmGcMetrics implements IMetricSet, AutoCloseable {
private static final Logger logger = LoggerFactory.getLogger(JvmGcMetrics.class); private static final Logger logger = LoggerFactory.getLogger(JvmGcMetrics.class);
private final List<Runnable> notificationListenerCleanUpRunnables = new CopyOnWriteArrayList<>(); private final List<Runnable> notificationListenerCleanUpRunnables = new CopyOnWriteArrayList<>();
private String youngGenPoolName; private String firstYoungGenPoolName;
private String oldGenPoolName; private String oldGenPoolName;
private String nonGenerationalMemoryPool; private String nonGenerationalMemoryPool;
private final Map<String, AtomicLong> lastGcTotalDurationMap = new ConcurrentHashMap<>(); private final Map<String, AtomicLong> lastGcTotalDurationMap = new ConcurrentHashMap<>();
...@@ -62,8 +62,8 @@ public class JvmGcMetrics implements IMetricSet, AutoCloseable { ...@@ -62,8 +62,8 @@ public class JvmGcMetrics implements IMetricSet, AutoCloseable {
public JvmGcMetrics() { public JvmGcMetrics() {
for (MemoryPoolMXBean mbean : ManagementFactory.getMemoryPoolMXBeans()) { for (MemoryPoolMXBean mbean : ManagementFactory.getMemoryPoolMXBeans()) {
String name = mbean.getName(); String name = mbean.getName();
if (isYoungGenPool(name)) { if (isFirstYoungGenPool(name)) {
youngGenPoolName = name; firstYoungGenPoolName = name;
} else if (isOldGenPool(name)) { } else if (isOldGenPool(name)) {
oldGenPoolName = name; oldGenPoolName = name;
} else if (isNonGenerationalHeapPool(name)) { } else if (isNonGenerationalHeapPool(name)) {
...@@ -98,12 +98,8 @@ public class JvmGcMetrics implements IMetricSet, AutoCloseable { ...@@ -98,12 +98,8 @@ public class JvmGcMetrics implements IMetricSet, AutoCloseable {
} }
} }
private static boolean isConcurrentPhase(String cause, String name) { private static boolean isFirstYoungGenPool(String name) {
return "No GC".equals(cause) || "Shenandoah Cycles".equals(name); return name != null && name.endsWith("Eden Space");
}
private static boolean isYoungGenPool(String name) {
return name != null && (name.endsWith("Eden Space") || name.endsWith("Survivor Space"));
} }
private static boolean isOldGenPool(String name) { private static boolean isOldGenPool(String name) {
...@@ -142,26 +138,35 @@ public class JvmGcMetrics implements IMetricSet, AutoCloseable { ...@@ -142,26 +138,35 @@ public class JvmGcMetrics implements IMetricSet, AutoCloseable {
liveDataSize, liveDataSize,
AtomicLong::get); AtomicLong::get);
AtomicLong heapMemUsedPercentage = new AtomicLong(calculateMemoryUsagePercentage());
metricService.createAutoGauge(
SystemMetric.JVM_GC_MEMORY_USED_PERCENT.toString(),
MetricLevel.CORE,
heapMemUsedPercentage,
AtomicLong::get);
Counter allocatedBytes =
metricService.getOrCreateCounter(
SystemMetric.JVM_GC_MEMORY_ALLOCATED_BYTES.toString(), MetricLevel.CORE);
Counter promotedBytes = Counter promotedBytes =
(oldGenPoolName == null) (oldGenPoolName == null)
? null ? null
: metricService.getOrCreateCounter( : metricService.getOrCreateCounter(
SystemMetric.JVM_GC_MEMORY_PROMOTED_BYTES.toString(), MetricLevel.CORE); SystemMetric.JVM_GC_MEMORY_PROMOTED_BYTES.toString(), MetricLevel.CORE);
// start watching for GC notifications Counter nonGenAllocatedBytes =
final AtomicLong heapPoolSizeAfterGc = new AtomicLong(); (nonGenerationalMemoryPool == null)
? null
: metricService.getOrCreateCounter(
SystemMetric.JVM_GC_NON_GEN_MEMORY_ALLOCATED_BYTES.toString(), MetricLevel.CORE);
Counter oldGenAllocatedBytes =
(oldGenPoolName == null)
? null
: metricService.getOrCreateCounter(
SystemMetric.JVM_GC_OLD_MEMORY_ALLOCATED_BYTES.toString(), MetricLevel.CORE);
Counter youngGenAllocatedBytes =
(firstYoungGenPoolName == null)
? null
: metricService.getOrCreateCounter(
SystemMetric.JVM_GC_YOUNG_MEMORY_ALLOCATED_BYTES.toString(), MetricLevel.CORE);
final AtomicLong firstYoungHeapPoolSizeAfterGc = new AtomicLong();
// long live heap pool includes old gen heap pool and non-generation heap pool.
final AtomicLong longLivedHeapPoolSizeAfterGc = new AtomicLong();
// start watching for GC notifications
for (GarbageCollectorMXBean mbean : ManagementFactory.getGarbageCollectorMXBeans()) { for (GarbageCollectorMXBean mbean : ManagementFactory.getGarbageCollectorMXBeans()) {
if (!(mbean instanceof NotificationEmitter)) { if (!(mbean instanceof NotificationEmitter)) {
continue; continue;
...@@ -194,16 +199,15 @@ public class JvmGcMetrics implements IMetricSet, AutoCloseable { ...@@ -194,16 +199,15 @@ public class JvmGcMetrics implements IMetricSet, AutoCloseable {
previousTotal.set(total); previousTotal.set(total);
} }
String timerName;
if (isConcurrentPhase(gcCause, notificationInfo.getGcName())) {
timerName = "jvm_gc_concurrent_phase_time";
} else {
timerName = "jvm_gc_pause";
}
// create a timer with tags named by gcCause, which binds gcCause with gcDuration // create a timer with tags named by gcCause, which binds gcCause with gcDuration
Timer timer = Timer timer =
metricService.getOrCreateTimer( metricService.getOrCreateTimer(
timerName, MetricLevel.CORE, "action", gcAction, "cause", gcCause); SystemMetric.JVM_GC_PAUSE.toString(),
MetricLevel.CORE,
"action",
gcAction,
"cause",
gcCause);
timer.update(duration, TimeUnit.MILLISECONDS); timer.update(duration, TimeUnit.MILLISECONDS);
// add support for ZGC // add support for ZGC
...@@ -219,25 +223,6 @@ public class JvmGcMetrics implements IMetricSet, AutoCloseable { ...@@ -219,25 +223,6 @@ public class JvmGcMetrics implements IMetricSet, AutoCloseable {
pausesCount.inc(); pausesCount.inc();
} }
// monitoring old/young GC count, which is helpful for users to locate GC exception.
// Unfortunately, the JMX doesn't seem to provide an api for monitoring mixed gc in G1.
// In fact, JMX may treat mixed GCs as minor GCs.
if (GcGenerationAge.fromName(notificationInfo.getGcName()) == GcGenerationAge.OLD) {
Counter oldGcCounter =
metricService.getOrCreateCounter(
SystemMetric.JVM_GC_YOUNG_GC_COUNT.toString(), MetricLevel.CORE);
oldGcCounter.inc();
} else if (GcGenerationAge.fromName(notificationInfo.getGcName())
== GcGenerationAge.YOUNG) {
Counter youngGcCounter =
metricService.getOrCreateCounter(
SystemMetric.JVM_GC_OLD_GC_COUNT.toString(), MetricLevel.CORE);
youngGcCounter.inc();
}
// update memory usage percentage
heapMemUsedPercentage.set(calculateMemoryUsagePercentage());
// Update promotion and allocation counters // Update promotion and allocation counters
final Map<String, MemoryUsage> before = gcInfo.getMemoryUsageBeforeGc(); final Map<String, MemoryUsage> before = gcInfo.getMemoryUsageBeforeGc();
final Map<String, MemoryUsage> after = gcInfo.getMemoryUsageAfterGc(); final Map<String, MemoryUsage> after = gcInfo.getMemoryUsageAfterGc();
...@@ -246,8 +231,8 @@ public class JvmGcMetrics implements IMetricSet, AutoCloseable { ...@@ -246,8 +231,8 @@ public class JvmGcMetrics implements IMetricSet, AutoCloseable {
countPoolSizeDelta( countPoolSizeDelta(
gcInfo.getMemoryUsageBeforeGc(), gcInfo.getMemoryUsageBeforeGc(),
gcInfo.getMemoryUsageAfterGc(), gcInfo.getMemoryUsageAfterGc(),
allocatedBytes, nonGenAllocatedBytes,
heapPoolSizeAfterGc, longLivedHeapPoolSizeAfterGc,
nonGenerationalMemoryPool); nonGenerationalMemoryPool);
if (after.get(nonGenerationalMemoryPool).getUsed() if (after.get(nonGenerationalMemoryPool).getUsed()
< before.get(nonGenerationalMemoryPool).getUsed()) { < before.get(nonGenerationalMemoryPool).getUsed()) {
...@@ -272,8 +257,7 @@ public class JvmGcMetrics implements IMetricSet, AutoCloseable { ...@@ -272,8 +257,7 @@ public class JvmGcMetrics implements IMetricSet, AutoCloseable {
// GC (since in JMX, a minor GC of G1 may actually represent mixed GC, which collect // GC (since in JMX, a minor GC of G1 may actually represent mixed GC, which collect
// some obj in old gen region). To track the // some obj in old gen region). To track the
// live data size we record the value if we see a reduction in the old gen heap size // live data size we record the value if we see a reduction in the old gen heap size
// or // or after a major GC.
// after a major GC.
if (oldAfter < oldBefore if (oldAfter < oldBefore
|| GcGenerationAge.fromName(notificationInfo.getGcName()) || GcGenerationAge.fromName(notificationInfo.getGcName())
== GcGenerationAge.OLD) { == GcGenerationAge.OLD) {
...@@ -281,15 +265,21 @@ public class JvmGcMetrics implements IMetricSet, AutoCloseable { ...@@ -281,15 +265,21 @@ public class JvmGcMetrics implements IMetricSet, AutoCloseable {
final long oldMaxAfter = after.get(oldGenPoolName).getMax(); final long oldMaxAfter = after.get(oldGenPoolName).getMax();
maxDataSize.set(oldMaxAfter); maxDataSize.set(oldMaxAfter);
} }
countPoolSizeDelta(
gcInfo.getMemoryUsageBeforeGc(),
gcInfo.getMemoryUsageAfterGc(),
oldGenAllocatedBytes,
longLivedHeapPoolSizeAfterGc,
oldGenPoolName);
} }
if (youngGenPoolName != null) { if (firstYoungGenPoolName != null) {
countPoolSizeDelta( countPoolSizeDelta(
gcInfo.getMemoryUsageBeforeGc(), gcInfo.getMemoryUsageBeforeGc(),
gcInfo.getMemoryUsageAfterGc(), gcInfo.getMemoryUsageAfterGc(),
allocatedBytes, youngGenAllocatedBytes,
heapPoolSizeAfterGc, firstYoungHeapPoolSizeAfterGc,
youngGenPoolName); firstYoungGenPoolName);
} }
} }
}; };
...@@ -321,12 +311,22 @@ public class JvmGcMetrics implements IMetricSet, AutoCloseable { ...@@ -321,12 +311,22 @@ public class JvmGcMetrics implements IMetricSet, AutoCloseable {
metricService.remove(MetricType.AUTO_GAUGE, SystemMetric.JVM_GC_MAX_DATA_SIZE_BYTES.toString()); metricService.remove(MetricType.AUTO_GAUGE, SystemMetric.JVM_GC_MAX_DATA_SIZE_BYTES.toString());
metricService.remove( metricService.remove(
MetricType.AUTO_GAUGE, SystemMetric.JVM_GC_LIVE_DATA_SIZE_BYTES.toString()); MetricType.AUTO_GAUGE, SystemMetric.JVM_GC_LIVE_DATA_SIZE_BYTES.toString());
metricService.remove(MetricType.COUNTER, SystemMetric.JVM_GC_MEMORY_ALLOCATED_BYTES.toString());
metricService.remove(MetricType.AUTO_GAUGE, SystemMetric.JVM_GC_MEMORY_USED_PERCENT.toString());
if (oldGenPoolName != null) { if (nonGenerationalMemoryPool != null) {
metricService.remove( metricService.remove(
MetricType.COUNTER, SystemMetric.JVM_GC_MEMORY_PROMOTED_BYTES.toString()); MetricType.COUNTER, SystemMetric.JVM_GC_NON_GEN_MEMORY_ALLOCATED_BYTES.toString());
} else {
if (oldGenPoolName != null) {
metricService.remove(
MetricType.COUNTER, SystemMetric.JVM_GC_MEMORY_PROMOTED_BYTES.toString());
metricService.remove(
MetricType.COUNTER, SystemMetric.JVM_GC_OLD_MEMORY_ALLOCATED_BYTES.toString());
}
if (firstYoungGenPoolName != null) {
metricService.remove(
MetricType.COUNTER, SystemMetric.JVM_GC_YOUNG_MEMORY_ALLOCATED_BYTES.toString());
}
} }
// start watching for GC notifications // start watching for GC notifications
...@@ -342,13 +342,14 @@ public class JvmGcMetrics implements IMetricSet, AutoCloseable { ...@@ -342,13 +342,14 @@ public class JvmGcMetrics implements IMetricSet, AutoCloseable {
String gcCause = notificationInfo.getGcCause(); String gcCause = notificationInfo.getGcCause();
String gcAction = notificationInfo.getGcAction(); String gcAction = notificationInfo.getGcAction();
String timerName; metricService.remove(
if (isConcurrentPhase(gcCause, notificationInfo.getGcName())) { MetricType.TIMER,
timerName = "jvm_gc_concurrent_phase_time"; SystemMetric.JVM_GC_PAUSE.toString(),
} else { "action",
timerName = "jvm_gc_pause"; gcAction,
} "cause",
metricService.remove(MetricType.TIMER, timerName, "action", gcAction, "cause", gcCause); gcCause);
if (mbean.getName().equals("ZGC Cycles")) { if (mbean.getName().equals("ZGC Cycles")) {
metricService.remove( metricService.remove(
MetricType.COUNTER, SystemMetric.JVM_ZGC_CYCLES_COUNT.toString()); MetricType.COUNTER, SystemMetric.JVM_ZGC_CYCLES_COUNT.toString());
...@@ -356,13 +357,6 @@ public class JvmGcMetrics implements IMetricSet, AutoCloseable { ...@@ -356,13 +357,6 @@ public class JvmGcMetrics implements IMetricSet, AutoCloseable {
metricService.remove( metricService.remove(
MetricType.COUNTER, SystemMetric.JVM_ZGC_PAUSES_COUNT.toString()); MetricType.COUNTER, SystemMetric.JVM_ZGC_PAUSES_COUNT.toString());
} }
if (GcGenerationAge.fromName(notificationInfo.getGcName()) == GcGenerationAge.OLD) {
metricService.remove(
MetricType.COUNTER, SystemMetric.JVM_GC_YOUNG_GC_COUNT.toString());
} else if (GcGenerationAge.fromName(notificationInfo.getGcName())
== GcGenerationAge.YOUNG) {
metricService.remove(MetricType.COUNTER, SystemMetric.JVM_GC_OLD_GC_COUNT.toString());
}
}; };
NotificationEmitter notificationEmitter = (NotificationEmitter) mbean; NotificationEmitter notificationEmitter = (NotificationEmitter) mbean;
notificationEmitter.addNotificationListener( notificationEmitter.addNotificationListener(
...@@ -426,12 +420,6 @@ public class JvmGcMetrics implements IMetricSet, AutoCloseable { ...@@ -426,12 +420,6 @@ public class JvmGcMetrics implements IMetricSet, AutoCloseable {
notificationListenerCleanUpRunnables.forEach(Runnable::run); notificationListenerCleanUpRunnables.forEach(Runnable::run);
} }
public long calculateMemoryUsagePercentage() {
return (ManagementFactory.getMemoryMXBean().getHeapMemoryUsage().getUsed()
* 100
/ Runtime.getRuntime().maxMemory());
}
enum GcGenerationAge { enum GcGenerationAge {
OLD, OLD,
YOUNG, YOUNG,
......
...@@ -79,13 +79,13 @@ public enum SystemMetric { ...@@ -79,13 +79,13 @@ public enum SystemMetric {
JVM_THREADS_STATUS_THREADS("jvm_threads_states_threads"), JVM_THREADS_STATUS_THREADS("jvm_threads_states_threads"),
JVM_GC_MAX_DATA_SIZE_BYTES("jvm_gc_max_data_size_bytes"), JVM_GC_MAX_DATA_SIZE_BYTES("jvm_gc_max_data_size_bytes"),
JVM_GC_LIVE_DATA_SIZE_BYTES("jvm_gc_live_data_size_bytes"), JVM_GC_LIVE_DATA_SIZE_BYTES("jvm_gc_live_data_size_bytes"),
JVM_GC_MEMORY_ALLOCATED_BYTES("jvm_gc_memory_allocated_bytes"), JVM_GC_YOUNG_MEMORY_ALLOCATED_BYTES("jvm_gc_young_memory_allocated_bytes"),
JVM_GC_OLD_MEMORY_ALLOCATED_BYTES("jvm_gc_old_memory_allocated_bytes"),
JVM_GC_NON_GEN_MEMORY_ALLOCATED_BYTES("jvm_gc_non_gen_memory_allocated_bytes"),
JVM_GC_MEMORY_PROMOTED_BYTES("jvm_gc_memory_promoted_bytes"), JVM_GC_MEMORY_PROMOTED_BYTES("jvm_gc_memory_promoted_bytes"),
JVM_GC_MEMORY_USED_PERCENT("jvm_gc_memory_used_percent"), JVM_GC_PAUSE("jvm_gc_pause"),
JVM_ZGC_CYCLES_COUNT("jvm_zgc_cycles_count"), JVM_ZGC_CYCLES_COUNT("jvm_zgc_cycles_count"),
JVM_ZGC_PAUSES_COUNT("jvm_zgc_pauses_count"), JVM_ZGC_PAUSES_COUNT("jvm_zgc_pauses_count"),
JVM_GC_YOUNG_GC_COUNT("jvm_gc_old_gc_count"),
JVM_GC_OLD_GC_COUNT("jvm_gc_young_gc_count"),
JVM_GC_ACCUMULATED_TIME_PERCENTAGE("jvm_gc_accumulated_time_percentage"), JVM_GC_ACCUMULATED_TIME_PERCENTAGE("jvm_gc_accumulated_time_percentage"),
// net related // net related
RECEIVED_BYTES("received_bytes"), RECEIVED_BYTES("received_bytes"),
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册