Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import javax.inject.Singleton;
import javax.net.ssl.SSLContext;
Expand Down Expand Up @@ -163,6 +164,7 @@
import org.apache.pinot.spi.utils.InstanceTypeUtils;
import org.apache.pinot.spi.utils.NetUtils;
import org.apache.pinot.spi.utils.PinotMd5Mode;
import org.apache.pinot.spi.utils.ResourceUsageUtils;
import org.apache.pinot.sql.parsers.rewriter.QueryRewriterFactory;
import org.glassfish.hk2.utilities.binding.AbstractBinder;
import org.slf4j.Logger;
Expand Down Expand Up @@ -898,6 +900,13 @@ private void initControllerMetrics() {
Integer.getInteger(ZkSystemPropertyKeys.JUTE_MAXBUFFER, 0xfffff));
ControllerMetrics.register(_controllerMetrics);
_validationMetrics = new ValidationMetrics(_metricsRegistry);

_controllerMetrics.setOrUpdateGauge("jvmHeapUsedAfterGc", ResourceUsageUtils::getHeapUsedAfterGc);
if (_executorService instanceof ThreadPoolExecutor) {
ThreadPoolExecutor tpe = (ThreadPoolExecutor) _executorService;
_controllerMetrics.setOrUpdateGauge("asyncExecutorQueueDepth", () -> (long) tpe.getQueue().size());
_controllerMetrics.setOrUpdateGauge("asyncExecutorActiveThreads", () -> (long) tpe.getActiveCount());
}
}

private void initPinotFSFactory() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@

import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.MemoryPoolMXBean;
import java.lang.management.MemoryUsage;
import java.util.List;


public class ResourceUsageUtils {
Expand All @@ -40,4 +42,21 @@ public static long getMaxHeapSize() {
public static long getUsedHeapSize() {
return MEMORY_MX_BEAN.getHeapMemoryUsage().getUsed();
}

/**
* Returns heap bytes used immediately after the last GC, summed across all memory pools.
* More stable than {@link #getUsedHeapSize()} because it excludes short-lived objects allocated
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we want to exclude short lived objects, can we use OldGenGC metrics instead? Is there any documentation on why this method is better than well known OldGenGC and YoungGenGC methods?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right — looking at our existing metrics we already have g1_old_gen.used_after_gc, g1_survivor_space.used_after_gc, and full GC timing/count metrics for young, old, and concurrent generations. This new metric adds no signal that can't be derived by summing the existing pool metrics at the query layer. I'll remove it.

This metric will provide the summed value regardless of which gc we use. So if we were using zgc, we'll need to update our metric. So this is a nice to have only

* since the last collection.
*/
public static long getHeapUsedAfterGc() {
long total = 0;
List<MemoryPoolMXBean> pools = ManagementFactory.getMemoryPoolMXBeans();
for (MemoryPoolMXBean pool : pools) {
MemoryUsage collectionUsage = pool.getCollectionUsage();
if (collectionUsage != null && collectionUsage.getUsed() >= 0) {
total += collectionUsage.getUsed();
}
}
return total;
}
}
Loading