Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[GR-51307] Add GC NotificationEmitter Support #9799

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
3 changes: 3 additions & 0 deletions substratevm/mx.substratevm/suite.py
Original file line number Diff line number Diff line change
Expand Up @@ -1029,6 +1029,9 @@
"jdk.internal.misc",
"sun.security.jca",
],
"java.management": [
"sun.management",
],
},
"checkstyle": "com.oracle.svm.test",
"checkstyleVersion" : "10.7.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,21 +26,18 @@

import java.lang.management.ManagementFactory;

import javax.management.MBeanNotificationInfo;
import javax.management.NotificationEmitter;
import javax.management.NotificationFilter;
import javax.management.NotificationListener;
import javax.management.ObjectName;

import com.oracle.svm.core.Uninterruptible;
import com.oracle.svm.core.gc.AbstractGarbageCollectorMXBean;
import org.graalvm.nativeimage.Platform;
import org.graalvm.nativeimage.Platforms;

import com.oracle.svm.core.util.TimeUtils;
import com.sun.management.GcInfo;

import sun.management.Util;

public final class CompleteGarbageCollectorMXBean implements com.sun.management.GarbageCollectorMXBean, NotificationEmitter {
public final class CompleteGarbageCollectorMXBean extends AbstractGarbageCollectorMXBean {

@Platforms(Platform.HOSTED_ONLY.class)
public CompleteGarbageCollectorMXBean() {
Expand Down Expand Up @@ -83,24 +80,13 @@ public ObjectName getObjectName() {
}

@Override
public void removeNotificationListener(NotificationListener listener, NotificationFilter filter, Object handback) {
protected int gcThreadCount() {
return 1;
}

@Override
public void addNotificationListener(NotificationListener listener, NotificationFilter filter, Object handback) {
}

@Override
public void removeNotificationListener(NotificationListener listener) {
}

@Override
public MBeanNotificationInfo[] getNotificationInfo() {
return new MBeanNotificationInfo[0];
}

@Override
public GcInfo getLastGcInfo() {
return null;
@Uninterruptible(reason = Uninterruptible.CALLED_FROM_UNINTERRUPTIBLE_CODE, mayBeInlined = true)
public boolean isIncremental() {
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,15 @@
import com.oracle.svm.core.deopt.DeoptimizationSlotPacking;
import com.oracle.svm.core.deopt.DeoptimizedFrame;
import com.oracle.svm.core.deopt.Deoptimizer;
import com.oracle.svm.core.gc.MemoryPoolMXBeansProvider;
import com.oracle.svm.core.genscavenge.AlignedHeapChunk.AlignedHeader;
import com.oracle.svm.core.genscavenge.BasicCollectionPolicies.NeverCollect;
import com.oracle.svm.core.genscavenge.HeapAccounting.HeapSizes;
import com.oracle.svm.core.genscavenge.HeapChunk.Header;
import com.oracle.svm.core.genscavenge.UnalignedHeapChunk.UnalignedHeader;
import com.oracle.svm.core.genscavenge.remset.RememberedSet;
import com.oracle.svm.core.notification.GcNotifier;
import com.oracle.svm.core.notification.HasGcNotificationSupport;
import com.oracle.svm.core.graal.RuntimeCompilation;
import com.oracle.svm.core.heap.CodeReferenceMapDecoder;
import com.oracle.svm.core.heap.GC;
Expand Down Expand Up @@ -239,7 +242,10 @@ assert getCollectionEpoch().equal(data.getRequestingEpoch()) ||
Timer collectionTimer = timers.collection.open();
try {
ThreadLocalAllocation.disableAndFlushForAllThreads();
GenScavengeMemoryPoolMXBeans.singleton().notifyBeforeCollection();
MemoryPoolMXBeansProvider.get().notifyBeforeCollection();
if (HasGcNotificationSupport.get()) {
GcNotifier.singleton().beforeCollection(TimeUtils.roundNanosToMillis(collectionTimer.getOpenedTime() - Isolates.getCurrentStartNanoTime()));
}
HeapImpl.getAccounting().notifyBeforeCollection();

verifyHeap(Before);
Expand All @@ -254,9 +260,14 @@ assert getCollectionEpoch().equal(data.getRequestingEpoch()) ||

accounting.updateCollectionCountAndTime(completeCollection, collectionTimer.getMeasuredNanos());
HeapImpl.getAccounting().notifyAfterCollection();
GenScavengeMemoryPoolMXBeans.singleton().notifyAfterCollection();
MemoryPoolMXBeansProvider.get().notifyAfterCollection();
ChunkBasedCommittedMemoryProvider.get().afterGarbageCollection();

if (HasGcNotificationSupport.get()) {
GcNotifier.singleton().afterCollection(!completeCollection, cause, getCollectionEpoch().rawValue(),
TimeUtils.roundNanosToMillis(collectionTimer.getClosedTime() - Isolates.getCurrentStartNanoTime()));
}

printGCAfter(cause);
JfrGCHeapSummaryEvent.emit(JfrGCWhen.AFTER_GC);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@

import java.lang.management.MemoryUsage;

import org.graalvm.nativeimage.ImageSingletons;
import com.oracle.svm.core.gc.AbstractMemoryPoolMXBean;
import com.oracle.svm.core.gc.MemoryPoolMXBeansProvider;
import org.graalvm.nativeimage.Platform;
import org.graalvm.nativeimage.Platforms;
import org.graalvm.word.UnsignedWord;
Expand All @@ -36,11 +37,9 @@
import com.oracle.svm.core.SubstrateOptions;
import com.oracle.svm.core.util.VMError;

import jdk.graal.compiler.api.replacements.Fold;

public class GenScavengeMemoryPoolMXBeans {
static final String YOUNG_GEN_SCAVENGER = "young generation scavenger";
static final String COMPLETE_SCAVENGER = "complete scavenger";
public class GenScavengeMemoryPoolMXBeans implements MemoryPoolMXBeansProvider {
public static final String YOUNG_GEN_SCAVENGER = "young generation scavenger";
public static final String COMPLETE_SCAVENGER = "complete scavenger";
static final String EPSILON_SCAVENGER = "epsilon scavenger";

static final String EDEN_SPACE = "eden space";
Expand All @@ -66,21 +65,19 @@ public GenScavengeMemoryPoolMXBeans() {
}
}

@Fold
public static GenScavengeMemoryPoolMXBeans singleton() {
return ImageSingletons.lookup(GenScavengeMemoryPoolMXBeans.class);
}

@Override
public AbstractMemoryPoolMXBean[] getMXBeans() {
return mxBeans;
}

@Override
public void notifyBeforeCollection() {
for (AbstractMemoryPoolMXBean mxBean : mxBeans) {
mxBean.beforeCollection();
}
}

@Override
public void notifyAfterCollection() {
for (AbstractMemoryPoolMXBean mxBean : mxBeans) {
mxBean.afterCollection();
Expand All @@ -95,28 +92,28 @@ static final class EdenMemoryPoolMXBean extends AbstractMemoryPoolMXBean {
}

@Override
void beforeCollection() {
public void beforeCollection() {
updatePeakUsage(HeapImpl.getAccounting().getEdenUsedBytes());
}

@Override
void afterCollection() {
public void afterCollection() {
/* Nothing to do. */
}

@Override
UnsignedWord computeInitialValue() {
protected UnsignedWord computeInitialValue() {
return GCImpl.getPolicy().getInitialEdenSize();
}

@Override
public MemoryUsage getUsage() {
return memoryUsage(getCurrentUsage());
return memoryUsage(getUsedBytes());
}

@Override
public MemoryUsage getPeakUsage() {
updatePeakUsage(getCurrentUsage());
updatePeakUsage(getUsedBytes());
return memoryUsage(peakUsage.get());
}

Expand All @@ -125,9 +122,15 @@ public MemoryUsage getCollectionUsage() {
return memoryUsage(WordFactory.zero());
}

private static UnsignedWord getCurrentUsage() {
@Override
public UnsignedWord getUsedBytes() {
return HeapImpl.getAccounting().getEdenUsedBytes();
}

@Override
public UnsignedWord getCommittedBytes() {
return HeapImpl.getAccounting().getEdenUsedBytes().add(HeapImpl.getAccounting().getBytesInUnusedChunks());
}
}

static final class SurvivorMemoryPoolMXBean extends AbstractMemoryPoolMXBean {
Expand All @@ -138,17 +141,17 @@ static final class SurvivorMemoryPoolMXBean extends AbstractMemoryPoolMXBean {
}

@Override
void beforeCollection() {
public void beforeCollection() {
/* Nothing to do. */
}

@Override
void afterCollection() {
public void afterCollection() {
updatePeakUsage(HeapImpl.getAccounting().getSurvivorUsedBytes());
}

@Override
UnsignedWord computeInitialValue() {
protected UnsignedWord computeInitialValue() {
return GCImpl.getPolicy().getInitialSurvivorSize();
}

Expand All @@ -166,6 +169,11 @@ public MemoryUsage getPeakUsage() {
public MemoryUsage getCollectionUsage() {
return memoryUsage(HeapImpl.getAccounting().getSurvivorUsedBytes());
}

@Override
public UnsignedWord getUsedBytes() {
return HeapImpl.getAccounting().getSurvivorUsedBytes();
}
}

static final class OldGenerationMemoryPoolMXBean extends AbstractMemoryPoolMXBean {
Expand All @@ -176,17 +184,17 @@ static final class OldGenerationMemoryPoolMXBean extends AbstractMemoryPoolMXBea
}

@Override
void beforeCollection() {
public void beforeCollection() {
/* Nothing to do. */
}

@Override
void afterCollection() {
public void afterCollection() {
updatePeakUsage(HeapImpl.getAccounting().getOldUsedBytes());
}

@Override
UnsignedWord computeInitialValue() {
protected UnsignedWord computeInitialValue() {
return GCImpl.getPolicy().getInitialOldSize();
}

Expand All @@ -204,6 +212,11 @@ public MemoryUsage getPeakUsage() {
public MemoryUsage getCollectionUsage() {
return memoryUsage(HeapImpl.getAccounting().getOldUsedBytes());
}

@Override
public UnsignedWord getUsedBytes() {
return HeapImpl.getAccounting().getOldUsedBytes();
}
}

static final class EpsilonMemoryPoolMXBean extends AbstractMemoryPoolMXBean {
Expand All @@ -214,17 +227,17 @@ static final class EpsilonMemoryPoolMXBean extends AbstractMemoryPoolMXBean {
}

@Override
void beforeCollection() {
public void beforeCollection() {
throw VMError.shouldNotReachHereAtRuntime(); // ExcludeFromJacocoGeneratedReport
}

@Override
void afterCollection() {
public void afterCollection() {
throw VMError.shouldNotReachHereAtRuntime(); // ExcludeFromJacocoGeneratedReport
}

@Override
UnsignedWord computeInitialValue() {
protected UnsignedWord computeInitialValue() {
return GCImpl.getPolicy().getMinimumHeapSize();
}

Expand All @@ -243,5 +256,15 @@ public MemoryUsage getPeakUsage() {
public MemoryUsage getCollectionUsage() {
return memoryUsage(WordFactory.zero());
}

@Override
public UnsignedWord getUsedBytes() {
return HeapImpl.getAccounting().getUsedBytes();
}

@Override
public UnsignedWord getCommittedBytes() {
return HeapImpl.getAccounting().getCommittedBytes();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,21 +26,18 @@

import java.lang.management.ManagementFactory;

import javax.management.MBeanNotificationInfo;
import javax.management.NotificationEmitter;
import javax.management.NotificationFilter;
import javax.management.NotificationListener;
import javax.management.ObjectName;

import com.oracle.svm.core.Uninterruptible;
import org.graalvm.nativeimage.Platform;
import org.graalvm.nativeimage.Platforms;

import com.oracle.svm.core.gc.AbstractGarbageCollectorMXBean;
import com.oracle.svm.core.util.TimeUtils;
import com.sun.management.GcInfo;

import sun.management.Util;

public final class IncrementalGarbageCollectorMXBean implements com.sun.management.GarbageCollectorMXBean, NotificationEmitter {
public final class IncrementalGarbageCollectorMXBean extends AbstractGarbageCollectorMXBean {

@Platforms(Platform.HOSTED_ONLY.class)
public IncrementalGarbageCollectorMXBean() {
Expand Down Expand Up @@ -82,24 +79,13 @@ public ObjectName getObjectName() {
}

@Override
public void removeNotificationListener(NotificationListener listener, NotificationFilter filter, Object handback) {
protected int gcThreadCount() {
return 1;
}

@Override
public void addNotificationListener(NotificationListener listener, NotificationFilter filter, Object handback) {
}

@Override
public void removeNotificationListener(NotificationListener listener) {
}

@Override
public MBeanNotificationInfo[] getNotificationInfo() {
return new MBeanNotificationInfo[0];
}

@Override
public GcInfo getLastGcInfo() {
return null;
@Uninterruptible(reason = Uninterruptible.CALLED_FROM_UNINTERRUPTIBLE_CODE, mayBeInlined = true)
public boolean isIncremental() {
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import com.oracle.svm.core.SubstrateOptions;
import com.oracle.svm.core.feature.AutomaticallyRegisteredFeature;
import com.oracle.svm.core.feature.InternalFeature;
import com.oracle.svm.core.gc.MemoryPoolMXBeansProvider;
import com.oracle.svm.core.genscavenge.ChunkedImageHeapLayouter;
import com.oracle.svm.core.genscavenge.GenScavengeMemoryPoolMXBeans;
import com.oracle.svm.core.genscavenge.HeapImpl;
Expand Down Expand Up @@ -84,7 +85,7 @@ public void afterRegistration(AfterRegistrationAccess access) {
ImageSingletons.add(BarrierSetProvider.class, rememberedSet);

GenScavengeMemoryPoolMXBeans memoryPoolMXBeans = new GenScavengeMemoryPoolMXBeans();
ImageSingletons.add(GenScavengeMemoryPoolMXBeans.class, memoryPoolMXBeans);
ImageSingletons.add(MemoryPoolMXBeansProvider.class, memoryPoolMXBeans);
ImageSingletons.add(GCRelatedMXBeans.class, new GenScavengeRelatedMXBeans(memoryPoolMXBeans));
}

Expand Down
Loading