Java启动jar包设置内存分配详细说明

在微服务架构越来越盛行的情况下,我们通常一个系统都会拆成很多个小的服务,但是最终部署的时候又因为没有那么多服务器只能把多个服务部署在同一台服务器上,这个时候问题就来了,服务器内存不够,这个时候我们就需要对每个服务的内存开始精细分配,以达到充分利用每一台服务器的目的

首先来看一下我们用来启动 jar 包的常用命令

nohup java -Xms512m -Xmx512m -Xmn256m -Xss512k -server -XX:+HeapDumpOnOutOfMemoryError -jar your-application.jar > output.log 2>&1 &

下面我们来一点点的解析这行命令

nohup:
在后台运行命令并忽略挂起信号(这个应该都知道没什么好说的)。

-Xms512m:
含义:设置 JVM 初始堆内存大小为 512MB。
作用:JVM 启动时分配的初始内存大小,确保在应用程序启动时有足够的内存。

-Xmx512m:
含义:设置 JVM 最大堆内存大小为 512MB。
作用:JVM 运行过程中可以使用的最大内存限制,防止应用程序占用过多的系统内存。

-Xmn256m:
含义:设置新生代内存大小为 256MB。
作用:控制新生代(Young Generation)的大小,新生代用于存放新创建的对象。适当调整可以影响垃圾回收的频率和性能。

-Xss512k:
含义:设置每个线程的栈大小为 512KB。
作用:控制每个线程的栈内存大小。如果应用程序创建大量线程或有深度递归调用,需要适当调整该值。

-server:
含义:启用 JVM 的服务器模式。
作用:服务器模式针对长期运行的服务器应用程序进行了优化,包括更高级的编译优化和垃圾回收策略。

-XX:+HeapDumpOnOutOfMemoryError:
含义:在发生内存溢出错误(OutOfMemoryError)时生成堆转储文件。
作用:当应用程序由于内存不足而崩溃时,生成堆转储文件(heap dump),便于后续进行内存分析和调试。

知道了这些参数的含义以及作用,在使用的过程中还有些地方需要注意

调整堆内存大小:根据应用程序的实际内存需求,调整 -Xms 和 -Xmx的值。通常,初始堆大小(-Xms)和最大堆大小(-Xmx)应该设置为相同,以避免 JVM在运行过程中调整堆大小带来的开销。
-Xms1024m -Xmx1024m

新生代内存调整:新生代(-Xmn)的大小应该根据应用程序对象的生命周期进行调整。一般来说,新生代应占堆内存的 1/3 到1/4。
-Xmn512m

垃圾回收器选择:不同的垃圾回收器适用于不同类型的应用程序。常见的垃圾回收器有 G1、CMS 和 Parallel GC。可以根据应用程序的特点选择合适的垃圾回收器。
G1 垃圾回收器(适合具有低延迟要求的应用程序)
-XX:+UseG1GC
CMS 垃圾回收器(适合需要短暂停顿时间的应用程序)
-XX:+UseConcMarkSweepGC
并行垃圾回收器(适合高吞吐量要求的应用程序)
-XX:+UseParallelGC

元空间大小调整:调整元空间(Metaspace)大小,避免频繁的元空间扩展。
-XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=256m

垃圾回收日志:启用垃圾回收日志,以便于调试和优化垃圾回收。
-Xlog:gc*:file=gc.log:time,level,tags

线程栈大小调整:根据应用程序的线程使用情况调整线程栈大小。
-Xss1m

启用类数据共享
-XX:+UseAppCDS

启用自适应大小线程池:
-XX:+UseAdaptiveSizePolicy

综合一下就是下面这条命令

nohup java -Xms1024m -Xmx1024m -Xmn512m -Xss1m -server -XX:+HeapDumpOnOutOfMemoryError -XX:+UseG1GC -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=256m -Xlog:gc*:file=gc.log:time,level,tags -jar your-application.jar > output.log 2>&1 &

接着我们再来说一下简洁版的启动命令

nohup java -jar your-application.jar &

在没有指定任何 JVM 参数的情况下,使用 nohup java -jar your-application.jar & 启动 Java 应用程序时,JVM将使用默认的内存设置。这些默认值通常取决于 JVM 的版本、操作系统以及系统的可用内存。以下是一些默认设置的概述:

堆内存:
默认初始堆大小(-Xms):通常为物理内存的 1/64,但不超过 1GB。
默认最大堆大小(-Xmx):通常为物理内存的 1/4,但不超过32GB。

新生代内存:
新生代大小(-Xmn):默认情况下,新生代的大小会根据堆大小动态调整。

线程栈大小:
默认线程栈大小(-Xss):这取决于操作系统和 JVM 实现。通常在 Linux 上为 1MB,Windows 上为 320KB。

垃圾回收器:
JVM 会选择默认的垃圾回收器,这通常是并行垃圾回收器(Parallel GC),具体取决于 JVM 的版本。

元空间:
默认情况下,元空间(Metaspace)大小会动态调整。

这个呢大家也可以直接在服务器上查看

java -XX:+PrintFlagsFinal -version

也可以在程序运行时查看

public static void main(String[] args) {
        Runtime runtime = Runtime.getRuntime();
        long maxMemory = runtime.maxMemory();
        long allocatedMemory = runtime.totalMemory();
        long freeMemory = runtime.freeMemory();

        System.out.println("Max Memory: " + maxMemory / 1024 / 1024 + " MB");
        System.out.println("Allocated Memory: " + allocatedMemory / 1024 / 1024 + " MB");
        System.out.println("Free Memory: " + freeMemory / 1024 / 1024 + " MB");
    }

我这个就是本机默认的,明显有些大了

在这里插入图片描述

好了,合理分配内存,节约服务器空间从你我做起

  • 17
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 你可以使用 Java 命令来直接启动一个 jar 包。在命令行中输入以下命令: ``` java -jar yourJarFile.jar ``` 这将会启动你的 jar 包,并执行其中的主类。如果你的 jar 包中没有主类,那么会出现错误提示。 请注意,你需要确保你的系统已经安装了 Java 运行环境,并且将 Java 安装目录添加到了系统环境变量中,这样才能在命令行中调用 java 命令。 ### 回答2: 在Java中,我们可以通过命令行或脚本直接启动.jar文件。在命令行中,我们可以使用java命令来启动一个.jar文件。 首先,确保已经安装了Java Development Kit(JDK),并且已将其添加到系统的环境变量中。 然后,我们可以打开命令提示符或终端,并导航到存放.jar文件的目录。然后,运行以下命令启动.jar文件: java -jar 文件名.jar 其中,"文件名"是要启动的.jar文件的名称。执行该命令后,Java虚拟机将加载并执行所指定的.jar文件。 在启动.jar文件时,我们还可以使用一些可选的命令行参数来配置Java虚拟机的行为。例如,我们可以指定要分配给Java虚拟机的内存大小,使用以下命令: java -Xmx512m -jar 文件名.jar 在上述示例中,"-Xmx512m"表示将最大内存大小设置为512兆字节。 此外,我们还可以在脚本中编写一个启动.jar文件的批处理或Shell脚本。在脚本中,我们使用java命令来启动.jar文件,并可以通过传递参数来配置Java虚拟机的行为。 总而言之,我们可以通过使用命令行或脚本直接启动.jar文件来运行Java程序。这种方式非常方便,可以让我们在不需要编译Java代码的情况下快速运行程序。 ### 回答3: Java程序可以通过命令行或者编程方式直接启动jar包。在命令行中,可以使用`java -jar`命令来启动jar包。例如,如果有一个名为`hello.jar`的jar包,可以使用以下命令启动它: ``` java -jar hello.jar ``` 这样,Java虚拟机会加载并执行`hello.jar`中的主类。需要注意的是,jar包必须包含一个`MANIFEST.MF`文件,其中定义了包含`main()`方法的主类。在启动时,Java虚拟机会自动查找并执行该主类。 除了命令行启动,也可以通过编程方式启动一个jar包。可以使用Java的`ProcessBuilder`类来创建一个进程,然后通过指定java命令和jar包路径作为参数来启动jar包。以下是一个简单的示例: ```java import java.io.IOException; public class Main { public static void main(String[] args) { try { ProcessBuilder pb = new ProcessBuilder("java", "-jar", "hello.jar"); Process process = pb.start(); // 可以通过process对象获取输出、错误信息等 // 等待进程执行完毕 int exitCode = process.waitFor(); System.out.println("程序执行完毕,退出码为:" + exitCode); } catch (IOException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } } } ``` 以上代码创建了一个进程,使用`java`命令启动`hello.jar`。`ProcessBuilder`类提供了一些方法来控制进程的输入、输出、错误等。`process.waitFor()`方法可以等待进程执行完毕,并返回进程的退出码。 总之,Java程序可以通过命令行或者编程方式直接启动jar包。命令行启动更加简单,只需使用`java -jar`命令即可。编程启动则需要使用`ProcessBuilder`类来创建进程并启动jar包
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

子非衣

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值