JDK-8258917 : NativeMemoryTracking is handled by launcher inconsistenly
  • Type: Bug
  • Component: tools
  • Sub-Component: launcher
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2020-12-23
  • Updated: 2021-08-01
  • Resolved: 2021-01-22
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 17
17 b07Fixed
Related Reports
Blocks :  
Relates :  
Relates :  
There is inconsistency how launcher and hotspot handle -XX:NativeMemoryTracking for non-java(w)

For all launcher-based tools launcher ignores the parameter but hotspot handles it.
As a result VM warning is printed:
> jcmd -J-XX:NativeMemoryTracking=detail
Java HotSpot(TM) 64-Bit Server VM warning: Native Memory Tracking did not setup properly, using wrong launcher?
20508 jdk.jcmd/sun.tools.jcmd.JCmd

> jar -J-XX:NativeMemoryTracking=detail
Java HotSpot(TM) 64-Bit Server VM warning: Native Memory Tracking did not setup properly, using wrong launcher?
Usage: jar [OPTION...] [ [--release VERSION] [-C dir] files] ...
Try `jar --help' for more information.

As far as I see from history, this was implemented this way initially (JDK-8042469), CCC request tells nothing about java/non-java launcher differences.

Note that the upcoming JDK-8256844 "Make NMT late-initializable" reworks NMT initialization logic, making NMT arguments "non-special" and removing the need for handling them in launchers.

Changeset: bdc305e1 Author: Alex Menkov <amenkov@openjdk.org> Date: 2021-01-22 21:33:02 +0000 URL: https://git.openjdk.java.net/jdk/commit/bdc305e1

After looking at JDK-8256844 I'm not sure the logic can be moved to after LoadJavaVM after all. If NMT initializes through C++ static initialization that occurs when dl_open actually loads the library, rather than when CreateJavaVM initiates VM initialization, then the env var must already be in place. I don't see a simple fix that doesn't involve parsing the arg list more than once.

I don't like the idea to keep existing SetJvmEnvironment logic for java(w) and handle non-java case in TranslateApplicationArgs. This would make the logic more complicated. After researching the code I think we can execute SetJvmEnvironment logic after TranslateApplicationArgs. So it will be the same for both java & non-java cases. Actually I think the best approach is to handle NMT in ParseArguments - it already has logic to process only VM arguments (so corresponding logic from SetJvmEnvironment can be dropped)

It doesn't need to be done before LoadJavaVM. The actual JNI_CreateJavaVM call happens via the JVMInit call. TranslateApplicationArgs converts the -J-XX flags into plain -XX for the VM to see when it is created.

[~dholmes] The question is when we need to execute SetJvmEnvironment logic. if it needs to be executed before JVMInit then we can handle NativeMemoryTracking in TranslateApplicationArgs. But if we need to do this before LoadJavaVM then TranslateApplicationArgs is too late.

My main question initially was is there are reasons to not allow NMT in non-java(w) launchers. Looks like the answer is "no". So I'm going to fix this issue by myself.

Actually maybe not that complicated, but we can't easily determine when to stop processing the command-line args, so there could be a startup hit. Considering that further we do not want to parse the command-line twice in the IsJavaArgs case. So we should keep the existing logic as-is and then execute the core logic of SetJvmEnvironment when we find the requisite -J-XX:NativeMemoryTracking arg in TranslateApplicationArgs.

I've taken a detailed look at the code from both sides and as far as I can see the only reason this doesn't work for the other launchers is because of this: if (!IsJavaArgs()) { SetJvmEnvironment(argc,argv); } For the java launcher IsJavaArgs is false, whereas for the others it seems to be true (seen via _JAVA_LAUNCHER_DEBUG=true). To fix this would require much more complicated command-line parsing in SetJvmEnvironment to handle the -J-XX:NativeMemoryTracking=xxx form of the option.