Skip to content

Commit ad2776b

Browse files
Add initial support for JMX to Native Image.
Co-authored-by: Fabio Niephaus <[email protected]>
1 parent 53037a5 commit ad2776b

File tree

22 files changed

+1498
-8
lines changed

22 files changed

+1498
-8
lines changed

substratevm/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ This changelog summarizes major changes to GraalVM Native Image.
99
* (GR-41674) Class instanceOf and isAssignableFrom checks do need to make the checked type reachable.
1010
* (GR-41100) Add support for `-XX:HeapDumpPath` to control where heap dumps are created.
1111
* (GR-42148) Adjust build output to report types (primitives, classes, interfaces, and arrays) instead of classes and revise the output schema of `-H:BuildOutputJSONFile`.
12+
* (GR-40463) Red Hat added initial support for JMX, which can be enabled with the `--enable-monitoring` option (e.g. `--enable-monitoring=jmxclient,jmxserver`).
1213

1314
## Version 22.3.0
1415
* (GR-35721) Remove old build output style and the `-H:±BuildOutputUseNewStyle` option.

substratevm/mx.substratevm/suite.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,7 @@
262262
"jdk.internal.perf",
263263
"jdk.internal.ref",
264264
"jdk.internal.reflect",
265+
"jdk.internal.vm",
265266
"jdk.internal.util",
266267
],
267268
"java.desktop": [
@@ -275,6 +276,12 @@
275276
"jdk.management": [
276277
"com.sun.management.internal"
277278
],
279+
"jdk.management.agent": [
280+
"jdk.internal.agent",
281+
],
282+
"jdk.management.jfr": [
283+
"jdk.management.jfr"
284+
],
278285
"jdk.httpserver@19+": [
279286
"sun.net.httpserver.simpleserver",
280287
],
@@ -797,6 +804,9 @@
797804
"requires": [
798805
"java.compiler",
799806
"jdk.jfr",
807+
"java.management",
808+
"jdk.management.jfr",
809+
"java.rmi,"
800810
],
801811
"requiresConcealed" : {
802812
"java.base" : [
@@ -1262,6 +1272,8 @@
12621272
"java.net.http",
12631273
"jdk.sctp",
12641274
1275+
"jdk.management.agent",
1276+
"jdk.management.jfr",
12651277
],
12661278
"uses" : [
12671279
"org.graalvm.nativeimage.Platform",

substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/GCImpl.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ public final class GCImpl implements GC {
115115
private UnsignedWord sizeBefore = WordFactory.zero();
116116
private boolean collectionInProgress = false;
117117
private UnsignedWord collectionEpoch = WordFactory.zero();
118+
private long lastWholeHeapExaminedTimeNs = -1;
118119

119120
@Platforms(Platform.HOSTED_ONLY.class)
120121
GCImpl() {
@@ -287,6 +288,9 @@ private boolean doCollectOnce(GCCause cause, long requestingNanoTime, boolean co
287288
}
288289
scavenge(!complete);
289290
verifyAfterGC();
291+
if (complete) {
292+
lastWholeHeapExaminedTimeNs = System.nanoTime();
293+
}
290294
} finally {
291295
collectionTimer.close();
292296
}
@@ -1179,6 +1183,17 @@ public UnsignedWord getCollectionEpoch() {
11791183
return collectionEpoch;
11801184
}
11811185

1186+
/**
1187+
* Returns the time in ns that the last full GC happened relative to when the program was
1188+
* started. If no full GC has yet been run, it returns the time since the first allocation.
1189+
*/
1190+
public long getLastWholeHeapExaminedTimeNs() {
1191+
if (lastWholeHeapExaminedTimeNs < 0) {
1192+
return HeapImpl.getChunkProvider().getFirstAllocationTime();
1193+
}
1194+
return lastWholeHeapExaminedTimeNs;
1195+
}
1196+
11821197
public GCAccounting getAccounting() {
11831198
return accounting;
11841199
}

substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/HeapImpl.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -686,6 +686,11 @@ public void dirtyAllReferencesOf(Object obj) {
686686
}
687687
}
688688

689+
@Override
690+
public long getMaxObjectInspectionAge() {
691+
return (System.nanoTime() - getGCImpl().getLastWholeHeapExaminedTimeNs()) / 1000000;
692+
}
693+
689694
static Pointer getImageHeapStart() {
690695
int imageHeapOffsetInAddressSpace = Heap.getHeap().getImageHeapOffsetInAddressSpace();
691696
if (imageHeapOffsetInAddressSpace > 0) {

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/VMInspectionOptions.java

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,10 @@ public final class VMInspectionOptions {
4848
private static final String MONITORING_HEAPDUMP_NAME = "heapdump";
4949
private static final String MONITORING_JFR_NAME = "jfr";
5050
private static final String MONITORING_JVMSTAT_NAME = "jvmstat";
51-
private static final String MONITORING_ALLOWED_VALUES = "'" + MONITORING_HEAPDUMP_NAME + "', '" + MONITORING_JFR_NAME + "', '" + MONITORING_JVMSTAT_NAME + "', or '" + MONITORING_ALL_NAME +
52-
"' (defaults to '" + MONITORING_ALL_NAME + "' if no argument is provided)";
51+
private static final String MONITORING_JMXCLIENT_NAME = "jmxclient";
52+
private static final String MONITORING_JMXSERVER_NAME = "jmxserver";
53+
private static final String MONITORING_ALLOWED_VALUES = "'" + MONITORING_HEAPDUMP_NAME + "', '" + MONITORING_JFR_NAME + "', '" + MONITORING_JVMSTAT_NAME + "', '" + MONITORING_JMXSERVER_NAME +
54+
"', '" + MONITORING_JMXCLIENT_NAME + "', or '" + MONITORING_ALL_NAME + "' (defaults to '" + MONITORING_ALL_NAME + "' if no argument is provided)";
5355

5456
@APIOption(name = ENABLE_MONITORING_OPTION, defaultValue = MONITORING_ALL_NAME) //
5557
@Option(help = "Enable monitoring features that allow the VM to be inspected at run time. Comma-separated list can contain " + MONITORING_ALLOWED_VALUES + ". " +
@@ -59,7 +61,7 @@ public final class VMInspectionOptions {
5961

6062
public static void validateEnableMonitoringFeatures(OptionKey<?> optionKey) {
6163
Set<String> enabledFeatures = getEnabledMonitoringFeatures();
62-
enabledFeatures.removeAll(List.of(MONITORING_HEAPDUMP_NAME, MONITORING_JFR_NAME, MONITORING_JVMSTAT_NAME, MONITORING_ALL_NAME));
64+
enabledFeatures.removeAll(List.of(MONITORING_HEAPDUMP_NAME, MONITORING_JFR_NAME, MONITORING_JVMSTAT_NAME, MONITORING_JMXCLIENT_NAME, MONITORING_JMXSERVER_NAME, MONITORING_ALL_NAME));
6365
if (!enabledFeatures.isEmpty()) {
6466
throw UserError.abort("The option %s contains invalid value(s): %s. It can only contain %s.", optionKey.getName(), String.join(", ", enabledFeatures), MONITORING_ALLOWED_VALUES);
6567
}
@@ -94,6 +96,16 @@ public static boolean hasJvmstatSupport() {
9496
return hasAllOrKeywordMonitoringSupport(MONITORING_JVMSTAT_NAME) && !Platform.includedIn(WINDOWS.class);
9597
}
9698

99+
@Fold
100+
public static boolean hasJmxServerSupport() {
101+
return hasAllOrKeywordMonitoringSupport(MONITORING_JMXSERVER_NAME) && !Platform.includedIn(WINDOWS.class);
102+
}
103+
104+
@Fold
105+
public static boolean hasJmxClientSupport() {
106+
return hasAllOrKeywordMonitoringSupport(MONITORING_JMXCLIENT_NAME) && !Platform.includedIn(WINDOWS.class);
107+
}
108+
97109
@Option(help = "Dumps all runtime compiled methods on SIGUSR2.", type = OptionType.User) //
98110
public static final HostedOptionKey<Boolean> DumpRuntimeCompilationOnSignal = new HostedOptionKey<>(false, VMInspectionOptions::validateOnSignalOption);
99111

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/heap/Heap.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,4 +244,7 @@ public List<Class<?>> getLoadedClasses() {
244244
/** Consider all references in the given object as needing remembered set entries. */
245245
@Uninterruptible(reason = "Ensure that no GC can occur between modification of the object and this call.", callerMustBe = true)
246246
public abstract void dirtyAllReferencesOf(Object obj);
247+
248+
/** Returns time since the last full GC in milliseconds. */
249+
public abstract long getMaxObjectInspectionAge();
247250
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* Copyright (c) 2022, 2022, Oracle and/or its affiliates. All rights reserved.
3+
* Copyright (c) 2022, 2022, Red Hat Inc. All rights reserved.
4+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5+
*
6+
* This code is free software; you can redistribute it and/or modify it
7+
* under the terms of the GNU General Public License version 2 only, as
8+
* published by the Free Software Foundation. Oracle designates this
9+
* particular file as subject to the "Classpath" exception as provided
10+
* by Oracle in the LICENSE file that accompanied this code.
11+
*
12+
* This code is distributed in the hope that it will be useful, but WITHOUT
13+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15+
* version 2 for more details (a copy is included in the LICENSE file that
16+
* accompanied this code).
17+
*
18+
* You should have received a copy of the GNU General Public License version
19+
* 2 along with this work; if not, write to the Free Software Foundation,
20+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21+
*
22+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
23+
* or visit www.oracle.com if you need additional information or have any
24+
* questions.
25+
*/
26+
27+
package com.oracle.svm.core.jdk.management;
28+
29+
import java.util.function.BooleanSupplier;
30+
import com.oracle.svm.core.VMInspectionOptions;
31+
32+
public class JmxClientNotIncluded implements BooleanSupplier {
33+
@Override
34+
public boolean getAsBoolean() {
35+
return !VMInspectionOptions.hasJmxClientSupport();
36+
}
37+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* Copyright (c) 2022, 2022, Oracle and/or its affiliates. All rights reserved.
3+
* Copyright (c) 2022, 2022, Red Hat Inc. All rights reserved.
4+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5+
*
6+
* This code is free software; you can redistribute it and/or modify it
7+
* under the terms of the GNU General Public License version 2 only, as
8+
* published by the Free Software Foundation. Oracle designates this
9+
* particular file as subject to the "Classpath" exception as provided
10+
* by Oracle in the LICENSE file that accompanied this code.
11+
*
12+
* This code is distributed in the hope that it will be useful, but WITHOUT
13+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15+
* version 2 for more details (a copy is included in the LICENSE file that
16+
* accompanied this code).
17+
*
18+
* You should have received a copy of the GNU General Public License version
19+
* 2 along with this work; if not, write to the Free Software Foundation,
20+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21+
*
22+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
23+
* or visit www.oracle.com if you need additional information or have any
24+
* questions.
25+
*/
26+
27+
package com.oracle.svm.core.jdk.management;
28+
29+
import java.util.function.BooleanSupplier;
30+
31+
import com.oracle.svm.core.VMInspectionOptions;
32+
33+
public class JmxIncluded implements BooleanSupplier {
34+
@Override
35+
public boolean getAsBoolean() {
36+
return VMInspectionOptions.hasJmxServerSupport() || VMInspectionOptions.hasJmxClientSupport();
37+
}
38+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* Copyright (c) 2022, 2022, Oracle and/or its affiliates. All rights reserved.
3+
* Copyright (c) 2022, 2022, Red Hat Inc. All rights reserved.
4+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5+
*
6+
* This code is free software; you can redistribute it and/or modify it
7+
* under the terms of the GNU General Public License version 2 only, as
8+
* published by the Free Software Foundation. Oracle designates this
9+
* particular file as subject to the "Classpath" exception as provided
10+
* by Oracle in the LICENSE file that accompanied this code.
11+
*
12+
* This code is distributed in the hope that it will be useful, but WITHOUT
13+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15+
* version 2 for more details (a copy is included in the LICENSE file that
16+
* accompanied this code).
17+
*
18+
* You should have received a copy of the GNU General Public License version
19+
* 2 along with this work; if not, write to the Free Software Foundation,
20+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21+
*
22+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
23+
* or visit www.oracle.com if you need additional information or have any
24+
* questions.
25+
*/
26+
27+
package com.oracle.svm.core.jdk.management;
28+
29+
import java.util.function.BooleanSupplier;
30+
31+
import com.oracle.svm.core.VMInspectionOptions;
32+
33+
public class JmxServerIncluded implements BooleanSupplier {
34+
@Override
35+
public boolean getAsBoolean() {
36+
return VMInspectionOptions.hasJmxServerSupport();
37+
}
38+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* Copyright (c) 2022, 2022, Oracle and/or its affiliates. All rights reserved.
3+
* Copyright (c) 2022, 2022, Red Hat Inc. All rights reserved.
4+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5+
*
6+
* This code is free software; you can redistribute it and/or modify it
7+
* under the terms of the GNU General Public License version 2 only, as
8+
* published by the Free Software Foundation. Oracle designates this
9+
* particular file as subject to the "Classpath" exception as provided
10+
* by Oracle in the LICENSE file that accompanied this code.
11+
*
12+
* This code is distributed in the hope that it will be useful, but WITHOUT
13+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15+
* version 2 for more details (a copy is included in the LICENSE file that
16+
* accompanied this code).
17+
*
18+
* You should have received a copy of the GNU General Public License version
19+
* 2 along with this work; if not, write to the Free Software Foundation,
20+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21+
*
22+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
23+
* or visit www.oracle.com if you need additional information or have any
24+
* questions.
25+
*/
26+
27+
package com.oracle.svm.core.jdk.management;
28+
29+
import com.oracle.svm.core.util.VMError;
30+
31+
public class ManagementAgentStartupHook implements com.oracle.svm.core.jdk.RuntimeSupport.Hook {
32+
33+
@Override
34+
public void execute(boolean isFirstIsolate) {
35+
try {
36+
jdk.internal.agent.Agent.startAgent();
37+
} catch (Exception e) {
38+
throw VMError.shouldNotReachHere("ManagementFeature start-up hook failed: " + e);
39+
}
40+
}
41+
}

0 commit comments

Comments
 (0)