最近调试一些关于Java内存的东西,把之前一直没能整理,只是大概有个概念的东西翻出来了一下。
Java的命令行参数,在此前做web开发的时候,不是很常用到,如果完全没有用到过也能理解,毕竟没搞炸过,没gc过,jvm(sun jdk)的一些默认参数已经足够,web的东西只要环境相差不是太厉害,都没必要用到远程调试。
做过Java命令行工具开发的可能会使用一些,例如java -cp example.jar -option_a value_a 这样的技巧,或者封装一下成为一个工具包。用来给一些属性赋值,更新手的操作(也有可能是为了省事儿)会按一些例如,java -cp example.jar a b c 按顺序分别入参。对于一些框架,Apache MapReduce或是Spring Cloud这样的,就会看到-Dexample.options=xx这样的入参。
那这时候就会有一个问题,即框架、你自己的代码(程序入参)、jvm参数三方混一起的情况。也就是为什么要把它们区分开来,这样,我们自己设计一些参数的时候能够更加合理,有的权衡。
下面列出了一些目前我所知道的情况。
1.Java 命令行工具参数
例如:-verbose -jar -cp 之类的一些参数,这部分参数是Java可执行文件本身接受的参数。
具体可以参考sun官方给出的参数列表: https://docs.oracle.com/javase/10/tools/java.htm#JSWOR624
2.系统参数(不要和环境变量混掉)
例如:
-Djava.compiler=NONE -Djava.security.auth.login.config (例如kafka认证) ,这些以-D参数开头的,可以通过System.getProperty("key")取得,注意环境变量是System.getenv(),不要把它们搞混
这部分很难找到确切的参考,取决于你使用的框架,可以使用的系统变量大相径庭。关于Java 自身可以使用的,则可以在sun官方的指南中看到,具体放这边(失效可以搜索Java oracle tutorial,慢慢找)
https://docs.oracle.com/javase/tutorial/essential/environment/sysprop.html
关于上文也提到的
-Djava.security.auth.login.config 这个选项呢,则是JAAS标准的一部分,可以在这边找到参考,
https://docs.oracle.com/javase/8/docs/technotes/guides/security/jaas/JAASLMDevGuide.html
3.JVM参数
例如-X,以及-XX参数,这部分的参考就很多了,stackoverflow上面有个回答贴心的将它们分成4大类,当然也不一定要分类强迫症,大概理下思路可以
-
Non-Standard Options (prefixed with -X)
These options are general purpose options that are specific to the Java HotSpot Virtual Machine.
For example : -Xmssize, -Xmxsize
-
Advanced Runtime Options (prefixed with -XX) 运行时
These options control the runtime behavior of the Java HotSpot VM.
-
Advanced JIT Compiler Options (prefixed with -XX) JIT选项
These options control the dynamic just-in-time (JIT) compilation performed by the Java HotSpot VM.
-
Advanced Serviceability Options (prefixed with -XX) 服务指标(暂翻)
These options provide the ability to gather system information and perform extensive debugging.
-
Advanced Garbage Collection Options (prefixed with -XX) 垃圾回收
These options control how garbage collection (GC) is performed by the Java HotSpot VM.
具体可以看 https://docs.oracle.com/cd/E13150_01/jrockit_jvm/jrockit/jrdocs/refman/optionX.html
问题的本质:
入参问题的本质,在于java命令行工具按照约定(这部分我找不到规范,对openjdk没有研究,只知道兼容性各种报错)
将参数解析,然后发送往不同的部分,一部分是Java虚拟机要的,一部分是用户的主类要的,还有一部分是告诉工具自身如何寻址。当Java自身把自己需要的部分完全取走之后,剩下的就是用户主类的入参了,有点类似保留字,奈何没有规范,只能看到目前的参考去避让这部分。那难道我们自己的入参只能剩下依序吗?
于是回到我们最开始的问题,我们自己设计参数的时候,如果文明礼让地去避让上面的几大类,比如为避免和Java 参数相似,不用-; --;开头,同时为了不和框架混一起,不使用-D参数,自然也用不了-X -XX参数。真就按序解析?我的答案,学他们,
加前缀!或者你自身要开发一个框架,那不介意-D参数也可以,毕竟有系统API参数可以调用,何乐不为
就先写到这里,这么说吧,编程的东西,你不知道源头,很大程度上等于,你什么都不知道
PS,远程调试?check here_
https://docs.oracle.com/javase/8/docs/technotes/guides/jpda/