我无法通过_JAVA_OPTIONS
获取NMT设置。我的环境是kubernetes集群上的Docker容器,_JAVA_OPTIONS
包含启用NMT的标志(见下文)。
为了证明我已经创建了一个小型演示类Hello
,它每秒打印一行。
a)我在没有命令行参数的情况下运行Hello
:
[root@ticc-services-abo-3354894200-5fixb tmp]# echo $_JAVA_OPTIONS
-Xmx512m -Xms512m -XX:NativeMemoryTracking=summary
[root@ticc-services-abo-3354894200-5fixb tmp]# java Hello
Picked up _JAVA_OPTIONS: -Xmx512m -Xms512m -XX:NativeMemoryTracking=summary
hello 0
hello 1
...
在另一个控制台上,我尝试获取NTM摘要,但无法访问:
[root@ticc-services-abo-3354894200-5fixb /]# jcmd
Picked up _JAVA_OPTIONS: -Xmx512m -Xms512m -XX:NativeMemoryTracking=summary
1 /opt/abo.jar
740 Hello
766 sun.tools.jcmd.JCmd
[root@ticc-services-abo-3354894200-5fixb /]# jcmd 740 VM.native_memory
Picked up _JAVA_OPTIONS: -Xmx512m -Xms512m -XX:NativeMemoryTracking=summary
740:
Native memory tracking is not enabled
b)现在我直接在命令行上设置NMT标志:
[root@ticc-services-abo-3354894200-5fixb tmp]# java -XX:NativeMemoryTracking=summary Hello
Picked up _JAVA_OPTIONS: -Xmx512m -Xms512m -XX:NativeMemoryTracking=summary
hello 0
hello 1
...
和NMT的工作原理:
[root@ticc-services-abo-3354894200-5fixb tmp]# jcmd
Picked up _JAVA_OPTIONS: -Xmx512m -Xms512m -XX:NativeMemoryTracking=summary
1 /opt/abo.jar
834 Hello
846 sun.tools.jcmd.JCmd
[root@ticc-services-abo-3354894200-5fixb tmp]# jcmd 834 VM.native_memory summary
Picked up _JAVA_OPTIONS: -Xmx512m -Xms512m -XX:NativeMemoryTracking=summary
834:
Native Memory Tracking:
Total: reserved=1873866KB, committed=574898KB
- Java Heap (reserved=524288KB, committed=524288KB)
(mmap: reserved=524288KB, committed=524288KB)
...
修改Hello
以打印其堆总数和最大值后,我们看到-Xms
和-Xmx
被拾取但NMT标志没有,因为Java没有抱怨坏的NMT标志:
[root@ticc-services-abo-3354894200-5fixb tmp]# echo $_JAVA_OPTIONS
-Xmx256m -Xms128m -XX:NativeMemoryTracking=summary_FOO
[root@ticc-services-abo-3354894200-5fixb tmp]# java Hello
Picked up _JAVA_OPTIONS: -Xmx256m -Xms128m -XX:NativeMemoryTracking=summary_FOO
heap: total=128974848, max=239075328
hello 0
hello 1
hello 2
这是我的环境:
[root@ticc-services-abo-3354894200-5fixb /]# uname -a
Linux ticc-services-abo-3354894200-5fixb 4.7.3-coreos-r2 #1 SMP Tue Nov 1 01:38:43 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
[root@ticc-services-abo-3354894200-5fixb /]# java -version
Picked up _JAVA_OPTIONS: -Xmx512m -Xms512m -XX:NativeMemoryTracking=summary
java version "1.8.0_91"
Java(TM) SE Runtime Environment (build 1.8.0_91-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.91-b14, mixed mode)
这看起来很奇怪,所以任何提示或想法都非常欢迎。
答案 0 :(得分:0)
我相信您的计算机中存在的环境变量与启动该Java进程的VM参数之间存在混淆。
您可以将其命名为 _JAVA_OPTIONS,JAVA_OPTIONS,MY_STARTUP_OPTION 或任何其他名称,该名称没有什么特别的,它不是Java进程的保留字。
您的Java代码正在打印出该变量的值的事实也使其与众不同:
System.out.println("Picked up JAVA_OPTIONS: "+System.getenv("_JAVA_OPTIONS"));
System.out.println("Picked up JAVA_OPTIONS: "+System.getenv("JAVA_OPTIONS"));
对于此Java进程,它只是另一个常见的env变量。 这里重要的是要知道该变量是否用于启动您的过程,并根据本示例中显示的步骤顺序,答案是否定的。
如果希望使该变量用于启动该Java进程,则应使用:
java $JAVA_OPTIONS Hello
或
java $_JAVA_OPTIONS Hello
此外,要打印出此Java进程的VM参数,可以使用:
ManagementFactory.getRuntimeMXBean().getInputArguments();
这是完整的Java代码
import java.lang.management.ManagementFactory;
import java.util.List;
public class Hello {
public static void main(String[] args) {
int i = 0;
System.out.println("Picked up JAVA_OPTIONS: "+System.getenv("JAVA_OPTIONS"));
System.out.println("VMArguments: "+Hello.vmArguments().toString());
try {
while (true) {
System.out.println("hello " + (i++));
Thread.sleep(1000);
}
} catch (InterruptedException e) {
System.out.println("Good bye");
e.printStackTrace();
}
}
static List<String> vmArguments() {
return ManagementFactory.getRuntimeMXBean().getInputArguments();
}
}
还有一个执行示例:
C:\Hello\bin>echo %JAVA_OPTIONS%
-Xmx512m -Xms512m -XX:NativeMemoryTracking=summary
C:\Hello\bin>echo %MY_STARTUP_OPTION%
-XX:NativeMemoryTracking=detail
C:\Hello\bin>java %MY_STARTUP_OPTION% Hello
Picked up JAVA_OPTIONS: -Xmx512m -Xms512m -XX:NativeMemoryTracking=summary
VMArguments: [-XX:NativeMemoryTracking=detail]
hello 0
C:\Hello\bin>java %JAVA_OPTIONS% Hello
Picked up JAVA_OPTIONS: -Xmx512m -Xms512m -XX:NativeMemoryTracking=summary
VMArguments: [-Xmx512m, -Xms512m, -XX:NativeMemoryTracking=summary]
hello 0
在另一个终端上,您可以使用 $ JAVA_HOME / bin / jps 或 ps -fea | grep java 。 这是Windows中的示例:
C:\Users\MyUser>jps -lv
5644 Hello -Xmx512m -Xms512m -XX:NativeMemoryTracking=summary
我希望称为JAVA_OPTIONS的变量或任何env变量与VM参数之间的区别是明确的。
回到最初的问题我不确定,但是Kubernetes似乎使用了 JAVA_OPTS 环境变量。选中https://dev.to/sandrogiacom/kubernetes-for-java-developers-debug-application-4l1a
关于NMT的选项,官方文档中提到了“摘要”和“详细信息”。
参考:https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/tooldescr007.html
希望有帮助!