[服务器] JAVA_OPTS 参数含义说明 | tomcat

本文深入解析了Java虚拟机(JVM)内存管理机制,详细介绍了堆内存和非堆内存的分配,以及如何通过调整-Xms、-Xmx、-XX:PermSize和-XX:MaxPermSize等参数来优化内存配置,有效解决Java应用在不同机器上启动失败的问题。文章还特别针对出现PermGen space和Java heap space错误时的解决方法进行了阐述。
每个大小对应的报错(详情参见2#):

java.lang.OutOfMemoryError: PermGen space PermGen space  对应的大小:
  1. JAVA_OPTS="-server -XX:PermSize=64M -XX:MaxPermSize=128m
复制代码


java.lang.OutOfMemoryError: Java heap space Heap size 对应的大小:
  1. JAVA_OPTS="-server -Xms800m -Xmx800m -XX:MaxNewSize=256m"
复制代码

2G内存的完整配置:
  1. JAVA_OPTS="-server -Xms1400m -Xmx1400m -XX:MaxNewSize=256m -XX:PermSize=128M -XX:MaxPermSize=512m -Djava.awt.headless=true"
复制代码
Xms Xmx XX:PermSize XX:MaxPermSize
1. 各个参数的含义什么?
我们首先了解一下JVM内存管理的机制,然后再解释每个参数代表的含义。
堆(Heap)和非堆(Non-heap)内存
    按照官方的说法:“Java 虚拟机具有一个堆,堆是运行时数据区域,所有类实例和数组的内存均从此处分配。堆是在 Java 虚拟机启动时创建的。”“在JVM中堆之外的内存称为非堆内存(Non-heap memory)”。可以看出JVM主要管理两种类型的内存:堆和非堆。简单来说堆就是Java代码可及的内存,是留给开发人员使用的;非堆就是JVM留给自己用的,所以方法区、JVM内部处理或优化所需的内存(如JIT编译后的代码缓存)、每个类结构(如运行时常数池、字段和方法数据)以及方法和构造方法的代码都在非堆内存中。
堆内存分配
    JVM初始分配的内存由-Xms指定,默认是物理内存的1/64;JVM最大分配的内存由-Xmx指定,默认是物理内存的1/4。默认空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制;空余堆内存大于70% 时,JVM会减少堆直到-Xms的最小限制。因此服务器一般设置-Xms、-Xmx相等以避免在每次GC 后调整堆的大小。
非堆内存分配
    JVM使用-XX:PermSize设置非堆内存初始值,默认是物理内存的1/64;由XX:MaxPermSize设置最大非堆内存的大小,默认是物理内存的1/4。
JVM内存限制(最大值)
    首先JVM内存限制于实际的最大物理内存,假设物理内存无限大的话,JVM内存的最大值跟操作系统有很大的关系。简单的说就32位处理器虽然可控内存空间有4GB,但是具体的操作系统会给一个限制,这个限制一般是2GB-3GB(一般来说Windows系统下为1.5G-2G,Linux系统下为2G-3G),而64bit以上的处理器就不会有限制了。
2. 为什么有的机器我将-Xmx和-XX:MaxPermSize都设置为512M之后tomcat可以启动,而有些机器无法启动?
通过上面对JVM内存管理的介绍我们已经了解到JVM内存包含两种:堆内存和非堆内存,另外JVM最大内存首先取决于实际的物理内存和操作系统。所以说设置VM参数导致程序无法启动主要有以下几种原因:
1) 参数中-Xms的值大于-Xmx,或者-XX:PermSize的值大于-XX:MaxPermSize;
2) -Xmx的值和-XX:MaxPermSize的总和超过了JVM内存的最大限制,比如当前操作系统最大内存限制,或者实际的物理内存等等。说到实际物理内存这里需要说明一点的是,如果你的内存是1024MB,但实际系统中用到的并不可能是1024MB,因为有一部分被硬件占用了。

java.lang.OutOfMemoryError: PermGen space及其解决方法

PermGen space的全称是Permanent Generation space,是指内存的永久保存区域OutOfMemoryError: PermGen space从表面上看就是内存益出,解决方法也一定是加大内存。说说为什么会内存益出:这一部分用于存放Class和Meta的信息,Class在被 Load的时候被放入PermGen space区域,它和和存放Instance的Heap区域不同,GC(Garbage Collection)不会在主程序运行期对PermGen space进行清理,所以如果你的APP会LOAD很多CLASS的话,就很可能出现PermGen space错误。这种错误常见在web服务器对JSP进行pre compile的时候。改正方法:-Xms256m -Xmx256m -XX:MaxNewSize=256m -XX:MaxPermSize=256m 2、在tomcat中redeploy时出现outofmemory的错误. 可以有以下几个方面的原因: 
1,使用了proxool,因为proxool内部包含了一个老版本的cglib. 
2, log4j,最好不用,只用common-logging 
3, 老版本的cglib,快点更新到最新版。
4,更新到最新的hibernate3.2 3、
这里以tomcat环境为例,其它WEB服务器如jboss,weblogic等是同一个道理。
一、java.lang.OutOfMemoryError: PermGen space PermGen space的全称是Permanent Generation space,是指内存的永久保存区域, 这块内存主要是被JVM存放Class和Meta信息的,Class在被Loader时就会被放到PermGen space中, 它和存放类实例(Instance)的Heap区域不同,GC(Garbage Collection)不会在主程序运行期对 PermGen space进行清理,所以如果你的应用中有很多CLASS的话,就很可能出现PermGen space错误, 这种错误常见在web服务器对JSP进行pre compile的时候。如果你的WEB APP下都用了大量的第三方jar, 其大小超过了jvm默认的大小(4M)那么就会产生此错误信息了。
解决方法: 手动设置MaxPermSize大小修改TOMCAT_HOME/bin/catalina.sh 在“echo "Using CATALINA_BASE: $CATALINA_BASE"”上面加入以下行:
  1. JAVA_OPTS="-server -XX:PermSize=64M -XX:MaxPermSize=128m
复制代码
建议:将相同的第三方jar文件移置到tomcat/shared/lib目录下,这样可以达到减少jar 文档重复占用内存的目的。
二、java.lang.OutOfMemoryError: Java heap space Heap size 设置 JVM堆的设置是指java程序运行过程中JVM可以调配使用的内存空间的设置.JVM在启动的时候会自动设置Heap size的值,其初始空间(即-Xms)是物理内存的1/64,最大空间(-Xmx)是物理内存的1/4。可以利用JVM提供的-Xmn -Xms -Xmx等选项可进行设置。Heap size 的大小是Young Generation 和Tenured Generaion 之和。提示:在JVM中如果98%的时间是用于GC且可用的Heap size 不足2%的时候将抛出此异常信息。提示:Heap Size 最大不要超过可用物理内存的80%,一般的要将-Xms和-Xmx选项设置为相同,而-Xmn为1/4的-Xmx值。 
解决方法:手动设置Heap size 修改TOMCAT_HOME/bin/catalina.sh 在“echo "Using CATALINA_BASE: $CATALINA_BASE"”上面加入以下行:
  1. JAVA_OPTS="-server -Xms800m -Xmx800m -XX:MaxNewSize=256m"
复制代码
三、实例,以下给出1G内存环境下java jvm 的参数设置参考:
  1. JAVA_OPTS="-server -Xms800m -Xmx800m -XX:MaxNewSize=256m -XX:PermSize=64M -XX:MaxPermSize=256m -Djava.awt.headless=true"
复制代码



### 配置 Linux 环境下 Tomcat 的 `JAVA_OPTS` 参数调优 在 Linux 环境中,配置 Tomcat 的 `JAVA_OPTS` 是优化 JVM 性能的重要手段。`JAVA_OPTS` 用于设置 JVM 的启动参数,包括堆内存大小、垃圾回收器、GC 日志输出等关键配置。合理设置这些参数可以有效降低内存占用,提升 Tomcat 的稳定性和响应速度。 在 Tomcat 的 `bin` 目录下,可以通过创建 `setenv.sh` 文件来设置 `JAVA_OPTS`。这种方式优于直接修改 `catalina.sh`,因为 `setenv.sh` 是独立的配置文件,便于维护和版本控制。该方法在 Tomcat 8 及更高版本中被广泛使用[^1]。 ```bash # 创建 setenv.sh 文件 touch /path/to/tomcat/bin/setenv.sh chmod +x /path/to/tomcat/bin/setenv.sh ``` 编辑 `setenv.sh` 文件,设置 `JAVA_OPTS` 参数: ```bash #!/bin/sh # 设置 JVM 参数 JAVA_OPTS="-server -Xms2g -Xmx2g" JAVA_OPTS="$JAVA_OPTS -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m" JAVA_OPTS="$JAVA_OPTS -XX:+UseG1GC" JAVA_OPTS="$JAVA_OPTS -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:/var/log/tomcat/gc.log" JAVA_OPTS="$JAVA_OPTS -Dfile.encoding=UTF-8" ``` #### 参数说明- `-server`:启用 Server 模式,适用于长期运行的服务器应用,性能更优。 - `-Xms2g -Xmx2g`:设置 JVM 初始堆内存和最大堆内存均为 2GB,避免堆内存动态调整带来的性能损耗。通常建议将 `-Xms` 和 `-Xmx` 设置为相同值以提升性能[^5]。 - `-XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m`:设置元空间的初始大小和最大值,防止元空间无限增长导致内存溢出。JDK 1.8 之后元空间取代了永久代(PermGen)[^1]。 - `-XX:+UseG1GC`:启用 G1 垃圾回收器,适用于大堆内存和低延迟场景。 - `-XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:/var/log/tomcat/gc.log`:启用详细的 GC 日志记录,便于后续分析和优化。 - `-Dfile.encoding=UTF-8`:强制使用 UTF-8 编码,避免因平台差异导致的乱码问题。 此外,如果仅用于 Tomcat,推荐使用 `CATALINA_OPTS` 而非 `JAVA_OPTS`,因为 `JAVA_OPTS` 也可能被其他 Java 应用程序使用,而 `CATALINA_OPTS` 专用于 Tomcat 启动时的 JVM 参数设置[^2]。 --- ### 示例:完整的 `setenv.sh` 文件 ```bash #!/bin/sh # 设置 JVM 参数 CATALINA_OPTS="-server -Xms2g -Xmx2g" CATALINA_OPTS="$CATALINA_OPTS -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m" CATALINA_OPTS="$CATALINA_OPTS -XX:+UseG1GC" CATALINA_OPTS="$CATALINA_OPTS -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:/var/log/tomcat/gc.log" CATALINA_OPTS="$CATALINA_OPTS -Dfile.encoding=UTF-8" ``` --- ### 监控与调优建议 配置完成后,建议使用以下工具进行监控和调优: - `jstat`:实时查看 GC 情况,分析 GC 频率和效率。 - `jmap`:生成堆转储文件,用于排查内存泄漏。 - `VisualVM`:图形化工具,提供全面的 JVM 运行状态监控,包括内存、线程、GC 等。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值