JDK/JRE 8多Java进程内存分配相关技术咨询
Java进程与JVM内存配置常见问题解答
问题1:两个进程是在同一个JVM中执行,还是各自在独立JVM中执行?
每次执行java -jar命令,操作系统都会启动一个全新的Java进程,每个进程对应一个独立的JVM实例。这两个JVM完全隔离,各自拥有自己的内存空间、线程栈、类加载器等核心资源,彼此之间不会共享或干扰对方的运行。简单来说,就是两个完全独立的JVM进程。
问题2:-Xmx8G -Xms1G的堆内存配置是分别应用于每个JAR进程,还是为两个进程共用?
先澄清一个常见误区:默认情况下java命令不会自动读取JAVA_OPTS环境变量——这个变量是Tomcat、Maven这类Java工具的启动脚本约定的参数集合,如果你直接执行java -jar命令,需要显式把JAVA_OPTS拼到命令里才会生效,比如java $JAVA_OPTS -jar 1.jar。
假设你的场景已经让JAVA_OPTS的配置生效,那么每个JVM进程会单独应用这个配置:
- 第一个进程的堆内存初始值为1G,最大值为8G
- 第二个进程的堆内存初始值同样为1G,最大值同样为8G
两个进程的堆内存完全独立,理论上总最大堆内存可以达到16G(实际占用取决于程序的内存需求)。
问题3:若启动第一个JAR包时使用默认配置(java -jar 1.jar),启动第二个时指定参数java -jar 2.jar -Xmx12G,内存分配情况会是怎样?
这里有个关键的参数位置规则:JVM参数必须放在-jar参数之前,放在-jar之后的参数会被当作程序的命令行参数传递给JAR包的主类,不会被JVM解析。
所以你的命令java -jar 2.jar -Xmx12G里,-Xmx12G不会被JVM识别为堆内存配置,而是会作为程序参数传入第二个JAR包的主类。此时:
- 第一个进程:没有指定任何JVM参数,会使用JDK8的默认堆内存配置(初始堆通常是物理内存的1/64,最大堆是物理内存的1/4,具体可通过
java -XX:+PrintFlagsFinal -version命令查看) - 第二个进程:同样使用默认堆配置,
-Xmx12G完全不生效
如果想让第二个进程使用12G的最大堆,正确的命令应该是:
java -Xmx12G -jar 2.jar
这种情况下:
- 第一个进程保持默认堆配置
- 第二个进程的最大堆被设置为12G,初始堆如果没单独指定,会使用JDK8的默认值(命令行指定的JVM参数优先级高于默认配置和环境变量)
内容的提问来源于stack exchange,提问作者Java Dude
相关产品推荐
相关产品推荐

