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-58070] Update VisualVM documentation and add more validation for the option '--enable-monitoring'. #9862

Closed
wants to merge 1 commit into from
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
18 changes: 11 additions & 7 deletions docs/tools/visualvm.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,19 @@ VisualVM enables powerful yet easy-to-use Java tooling which includes heap analy

Immediately after startup, the tool shows all locally running Java processes in the Applications area, including the VisualVM process, itself.

### Using VisualVM with GraalVM Native Executables

> Note: VisualVM support for GraalVM native executables is not yet available on Windows.

When using GraalVM [Native Image](../reference-manual/native-image/README.md), VisualVM support is disabled by default.
VisualVM support can be enabled when building a native executable with the option `--enable-monitoring=jvmstat,heapdump`:
```shell
native-image --enable-monitoring=jvmstat,heapdump JavaApplication
```

### Capture a Heap Dump
To capture a heap dump of, for example, a Ruby application for later analysis, start your application and let it run for a few seconds to warm up.
To capture a heap dump for later analysis, start your application and let it run for a few seconds to warm up.
Then right-click its process in VisualVM and invoke the Heap Dump action.
A new heap viewer for the Ruby process opens.

__Note:__ Heap dump support must be explicitly enabled when using [Native Image](../reference-manual/native-image/README.md).
Add the `--enable-monitoring=heapdump,jvmstat` option when invoking the `native-image` tool to enable the heap dump feature and allow VisualVM to detect native executables via `jvmstat`.
This way your application will handle signals and capture a heap dump when it receives the `SIGUSR1` signal.
See the [Generating Native Heap Dumps](../reference-manual/native-image/guides/create-heap-dump-from-native-executable.md) page for details on capturing heap dumps from a native image process.

### Analyzing Objects
Initially the Summary view for the Java heap is displayed.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@
import com.oracle.svm.core.heap.dump.HeapDumping;
import com.oracle.svm.core.jdk.management.ManagementAgentModule;
import com.oracle.svm.core.option.APIOption;
import com.oracle.svm.core.option.HostedOptionKey;
import com.oracle.svm.core.option.AccumulatingLocatableMultiOptionValue;
import com.oracle.svm.core.option.HostedOptionKey;
import com.oracle.svm.core.option.RuntimeOptionKey;
import com.oracle.svm.core.option.SubstrateOptionsParser;
import com.oracle.svm.core.util.UserError;
Expand All @@ -63,6 +63,7 @@ public final class VMInspectionOptions {

private static final List<String> MONITORING_ALL_VALUES = List.of(MONITORING_HEAPDUMP_NAME, MONITORING_JFR_NAME, MONITORING_JVMSTAT_NAME, MONITORING_JMXCLIENT_NAME, MONITORING_JMXSERVER_NAME,
MONITORING_THREADDUMP_NAME, MONITORING_NMT_NAME, MONITORING_ALL_NAME, MONITORING_DEFAULT_NAME);
private static final List<String> NOT_SUPPORTED_ON_WINDOWS = List.of(MONITORING_HEAPDUMP_NAME, MONITORING_JFR_NAME, MONITORING_JVMSTAT_NAME, MONITORING_JMXCLIENT_NAME, MONITORING_JMXSERVER_NAME);
private static final String MONITORING_ALLOWED_VALUES_TEXT = "'" + MONITORING_HEAPDUMP_NAME + "', '" + MONITORING_JFR_NAME + "', '" + MONITORING_JVMSTAT_NAME + "', '" + MONITORING_JMXSERVER_NAME +
"' (experimental), '" + MONITORING_JMXCLIENT_NAME + "' (experimental), '" + MONITORING_THREADDUMP_NAME + "', '" + MONITORING_NMT_NAME + "' (experimental), or '" +
MONITORING_ALL_NAME + "' (deprecated behavior: defaults to '" + MONITORING_ALL_NAME + "' if no argument is provided)";
Expand Down Expand Up @@ -93,11 +94,22 @@ public static void validateEnableMonitoringFeatures(@SuppressWarnings("unused")
getDefaultMonitoringCommandArgument(),
SubstrateOptionsParser.commandArgument(EnableMonitoringFeatures, String.join(",", List.of(MONITORING_HEAPDUMP_NAME, MONITORING_JFR_NAME))));
}

enabledFeatures.removeAll(MONITORING_ALL_VALUES);
if (!enabledFeatures.isEmpty()) {
throw UserError.abort("The '%s' option contains invalid value(s): %s. It can only contain %s.", getDefaultMonitoringCommandArgument(), String.join(", ", enabledFeatures),
MONITORING_ALLOWED_VALUES_TEXT);
}

if (Platform.includedIn(WINDOWS.class)) {
Set<String> notSupported = getEnabledMonitoringFeatures();
notSupported.retainAll(NOT_SUPPORTED_ON_WINDOWS);
if (!notSupported.isEmpty()) {
String warning = String.format("the option '%s' contains value(s) that are not supported on Windows: %s. Those values will be ignored.", getDefaultMonitoringCommandArgument(),
String.join(", ", notSupported));
LogUtils.warning(warning);
}
}
}

@Platforms(Platform.HOSTED_ONLY.class)
Expand Down