Linux系统启动jar包–Java8
启动命令及参数
1. 启动命令模板
nohup java \
-Xms512m \
-Xmx1024m \
-Xmn256m \
-XX:MetaspaceSize=128m \
-XX:MaxMetaspaceSize=256m \
-XX:+UseG1GC \
-XX:InitiatingHeapOccupancyPercent=45 \
-XX:+PrintGCDetails \
-XX:+PrintGCDateStamps \
-XX:+PrintGCApplicationStoppedTime \
-XX:+PrintGCApplicationConcurrentTime \
-Xloggc:logs/gc.log \
-XX:+HeapDumpOnOutOfMemoryError \
-XX:HeapDumpPath=logs/dump.hprof \
-Dfile.encoding=UTF-8 \
-Dspring.profiles.active=prod \
-jar mdy_lcpd-0.0.1-SNAPSHOT.jar > logs/app.log 2>&1 &
2. 参数详解
堆内存参数
-Xms512m
:设置 JVM 堆的初始内存为 512 MB。-Xmx1024m
:设置 JVM 堆的最大内存为 1024 MB。-Xmn256m
:设置新生代大小为 256 MB,用于存储短生命周期的对象(例如临时变量)。- 调整建议:
- 堆大小(
-Xms
和-Xmx
)应设置为相同值,避免堆的动态调整导致性能抖动。 - 新生代(
-Xmn
)通常为堆大小的 1/4 到 1/3。
- 堆大小(
元空间参数
-XX:MetaspaceSize=128m
:设置元空间的初始大小为 128 MB。元空间主要用于存储类的元信息。-XX:MaxMetaspaceSize=256m
:设置元空间的最大大小为 256 MB。- 说明:
- 元空间的大小默认与物理内存相关,如果类加载较多,建议增加
MaxMetaspaceSize
。 - 元空间使用本地内存(而非堆内存),因此不会对堆大小造成直接影响。
- 元空间的大小默认与物理内存相关,如果类加载较多,建议增加
垃圾回收参数
-XX:+UseG1GC
:启用 G1 垃圾回收器(默认推荐垃圾回收器,适合低延迟应用)。-XX:InitiatingHeapOccupancyPercent=45
:设置堆使用率达到 45% 时触发垃圾回收。- 可选 GC 调优参数:
-XX:MaxGCPauseMillis=200
:设置期望的最大 GC 停顿时间为 200 毫秒。-XX:+UseParallelGC
:启用并行 GC(适合吞吐量优先的场景)。-XX:+UseConcMarkSweepGC
:启用 CMS GC(适合低延迟场景,但已被 G1 替代)。
GC 日志参数
-XX:+PrintGCDetails
:打印详细的垃圾回收日志。-XX:+PrintGCDateStamps
:为 GC 日志添加时间戳。-XX:+PrintGCApplicationStoppedTime
:记录因 GC 导致的程序暂停时间。-XX:+PrintGCApplicationConcurrentTime
:记录应用执行的并发时间。-Xloggc:logs/gc.log
:将 GC 日志保存到logs/gc.log
文件中。
内存溢出调试
-XX:+HeapDumpOnOutOfMemoryError
:当发生内存溢出(OOM)时生成堆转储文件。-XX:HeapDumpPath=logs/dump.hprof
:指定堆转储文件的保存路径。
编码参数
-Dfile.encoding=UTF-8
:设置默认的文件编码为 UTF-8,防止中文乱码。
Spring 环境参数
-Dspring.profiles.active=prod
:指定 Spring 的激活环境为prod
(生产环境)。
3. 日志与目录结构建议
日志目录
logs/app.log
:保存应用运行日志。logs/gc.log
:保存垃圾回收日志。logs/dump.hprof
:当发生内存溢出时保存的堆转储文件。
创建日志目录
启动命令之前,确保创建 logs
文件夹:
mkdir logs
4. JVM 参数调优参考表
参数 | 描述 | 建议值 |
---|---|---|
-Xms / -Xmx | 设置堆的初始大小和最大大小 | 512m~2g |
-Xmn | 新生代大小 | 堆大小的 1/4~1/3 |
-XX:MetaspaceSize | 元空间的初始大小 | 128m |
-XX:MaxMetaspaceSize | 元空间的最大大小 | 256m 或更大 |
-XX:+UseG1GC | 启用 G1 垃圾回收器 | 低延迟或吞吐量场景推荐 |
-XX:MaxGCPauseMillis | 设置期望的最大 GC 停顿时间 | 100~500 毫秒 |
-XX:+PrintGCDetails | 打印 GC 详细信息 | 调试时推荐 |
-XX:+HeapDumpOnOutOfMemoryError | 内存溢出时生成堆转储文件 | 必须启用 |
-Dspring.profiles.active | 激活 Spring 配置环境 | prod 或 test |
5. 监控和排查
查看运行状态
ps -ef | grep mdy_lcpd-0.0.1-SNAPSHOT.jar
查看应用日志
tail -f logs/app.log
检查 GC 日志
cat logs/gc.log
6. 总结
- Java 8 的永久代被元空间(Metaspace)取代,内存管理更高效。
- 使用 G1 垃圾回收器 是生产环境的推荐配置,适用于低延迟和高吞吐量场景。
- 合理设置堆大小(
-Xms
和-Xmx
)和元空间大小(MetaspaceSize
和MaxMetaspaceSize
),确保性能稳定。 - 通过 GC 日志和堆转储文件,可以快速排查内存泄漏和性能问题。
参数默认值
在 Java 8 中,如果不设置上述 JVM 参数,JVM 会根据默认配置和运行环境自动分配内存和垃圾回收策略。以下是每个参数的默认值和行为:
1. 堆内存参数
默认值
-Xms
(初始堆大小):- 默认值为物理内存的 1/64,但最大不超过 1GB。
- 示例:如果服务器有 8GB 内存,默认初始堆大小为 128MB。
-Xmx
(最大堆大小):- 默认值为物理内存的 1/4,但最大不超过 1GB。
- 示例:如果服务器有 8GB 内存,默认最大堆大小为 2GB。
-Xmn
(新生代大小):- 默认值由 JVM 根据堆的总大小自动计算,通常占堆大小的 1/4 到 1/3。
不设置的影响
- JVM 会动态调整内存大小,可能导致频繁的垃圾回收,影响性能。
- 初始堆较小可能导致频繁扩容,增加系统开销。
- 最大堆较小时,容易出现
OutOfMemoryError
。
2. 元空间参数
默认值
-XX:MetaspaceSize
(元空间初始大小):- 默认值为 21MB。
-XX:MaxMetaspaceSize
(元空间最大大小):- 默认值没有限制,会根据操作系统的可用内存动态扩展。
不设置的影响
- 元空间扩展是动态的,但如果类加载过多且未限制最大值,可能导致过多的内存分配,消耗系统资源。
- 在高并发或大量类加载的场景下,容易发生
OutOfMemoryError: Metaspace
。
3. 垃圾回收参数
默认值
- 垃圾回收器:
- Java 8 默认使用 Parallel GC(并行垃圾回收器,吞吐量优先)。
- 并行 GC 默认行为:
- 新生代使用多线程进行垃圾回收。
- 老年代使用单线程回收。
不设置的影响
- 如果吞吐量优先,默认的 Parallel GC 适合大多数场景,但会有较高的 GC 停顿时间。
- 如果低延迟是主要需求,建议手动切换到 G1 GC。
4. GC 日志参数
默认值
- 默认不会打印 GC 日志。
- 没有启用日志参数(如
-XX:+PrintGCDetails
或-Xloggc
),你无法看到垃圾回收的详细信息。
不设置的影响
- 如果应用程序出现性能问题或内存问题,难以调试和定位问题。
5. 内存溢出调试
默认值
-XX:+HeapDumpOnOutOfMemoryError
:默认关闭。-XX:HeapDumpPath
:如果未指定路径,会将堆转储文件保存在当前工作目录。
不设置的影响
- 当发生内存溢出时,无法生成堆转储文件,增加问题排查的难度。
6. 文件编码参数
默认值
-Dfile.encoding
:- 默认编码与操作系统相关:
- Windows:
GBK
。 - Linux/Unix:
UTF-8
。
- Windows:
- 默认编码与操作系统相关:
不设置的影响
- 默认编码可能导致字符集不一致,尤其在不同操作系统之间运行时容易出现中文乱码问题。
7. Spring 环境参数
默认值
- 如果不指定
-Dspring.profiles.active
,Spring 不会激活任何特定的配置环境。
不设置的影响
- Spring 应用会使用默认配置文件(
application.properties
或application.yml
),可能导致在生产环境中使用了开发环境配置。
总结:默认值对比表
参数 | 默认值 | 不设置的影响 |
---|---|---|
-Xms | 物理内存的 1/64,最大 1GB | 启动时堆较小,扩容频繁,性能抖动 |
-Xmx | 物理内存的 1/4,最大 1GB | 最大堆较小,容易出现 OutOfMemoryError |
-Xmn | 堆大小的 1/4~1/3 | 新生代较小时,频繁触发 Minor GC |
-XX:MetaspaceSize | 21MB | 元空间扩容频繁,可能影响性能 |
-XX:MaxMetaspaceSize | 无限制(操作系统内存限制) | 元空间过大可能耗尽系统内存 |
-XX:+UseG1GC | 默认使用 Parallel GC | 延迟较高的场景性能不佳 |
GC 日志参数 | 未启用 | 无法调试垃圾回收相关问题 |
-XX:+HeapDumpOnOutOfMemoryError | 默认关闭 | 内存溢出时无法生成堆转储文件,增加排查难度 |
-Dfile.encoding | 与操作系统相关 | 不同环境可能导致中文乱码 |
-Dspring.profiles.active | 默认未激活配置环境 | 默认使用开发环境配置,可能导致问题 |
优化建议
- 内存设置:
- 生产环境应显式设置
-Xms
和-Xmx
,避免动态扩展引发的性能抖动。
- 生产环境应显式设置
- 元空间:
- 限制
MaxMetaspaceSize
,防止元空间耗尽系统内存。
- 限制
- 垃圾回收:
- 吞吐量优先使用 Parallel GC,低延迟场景切换到 G1 GC。
- 日志:
- 打开 GC 日志和堆转储功能,便于排查问题。
- 编码:
- 显式设置
-Dfile.encoding=UTF-8
,确保字符集一致性。
- 显式设置
- Spring 环境:
- 在生产环境中激活
prod
配置,避免配置混淆。
- 在生产环境中激活
JVM大小限制与不限制
1. 不限制 JVM 大小
优点
- 更灵活:JVM 会根据需要动态调整内存使用,初始分配较少,当需要更多内存时会向操作系统申请。
- 配置简单:不需要手动设置
-Xms
和-Xmx
等参数。
缺点
- 可能过度占用系统内存:如果程序中存在内存泄漏或高内存需求场景(如大数据处理、大量对象实例化),JVM 会一直向操作系统申请更多内存,最终可能导致系统内存耗尽,甚至引发系统性能下降。
- GC 不够高效:堆空间过大会导致垃圾回收(GC)所需的时间增加,尤其是 Full GC。
- 无法预测资源使用:在生产环境中,无法确定应用程序的内存占用,可能影响同一台服务器上其他服务的稳定性。
2. 限制 JVM 大小
优点
- 更可控:设置了
-Xms
和-Xmx
后,JVM 会在固定范围内分配内存,防止程序无限制占用系统资源。 - 提升 GC 效率:限制堆大小可以更好地控制 GC 的行为,避免堆空间过大导致的 GC 时间增加。
- 更适合生产环境:在多服务部署的环境中,限制 JVM 内存可以让每个服务有明确的资源界限,保证系统的整体稳定性。
- 优化性能:通过合理设置堆大小,避免频繁的垃圾回收,同时减少 Full GC 的时间。
缺点
- 需要调优:如果限制的内存过小,可能导致
OutOfMemoryError
异常(OOM),需要根据实际应用需求调整参数。 - 初始内存分配较大:设置较大的
-Xms
会让 JVM 启动时就分配较多内存,即使实际不需要,也可能浪费资源。
实际影响对比
影响点 | 不限制 JVM 大小 | 限制 JVM 大小 |
---|---|---|
内存分配 | 动态调整,可能占用系统全部可用内存 | 固定在指定范围内,系统资源分配更可控 |
GC 行为 | 堆空间可能过大,GC 耗时较长 | 合理的堆大小提升 GC 效率,避免内存过小或过大 |
系统稳定性 | 可能对其他服务造成影响,甚至引发系统崩溃 | 稳定性更高,避免单一服务消耗过多内存 |
应用启动速度 | 初始堆较小时启动较快,但动态调整堆内存可能耗时 | 初始堆较大时启动稍慢,但内存调整行为更可预测 |
调试和监控 | 难以预测和复现内存问题 | 更容易发现和定位内存不足或内存泄漏问题 |
总结
在开发和测试环境中,如果资源充足,可以不限制 JVM 大小,以便观察应用程序的实际内存使用需求。但在生产环境中,必须限制 JVM 内存大小,尤其是高并发或多服务部署的场景。合理设置 -Xms
和 -Xmx
等参数,可以保证性能和稳定性,同时避免资源竞争。