JVM启动参数设置

本文深入探讨了Java应用程序中常见的内存溢出问题,包括java.lang.OutOfMemoryError:JavaHeapSpace和java.lang.OutOfMemoryError:PermGenSpace两种类型。详细解释了如何通过JVM参数-Xms、-Xmx、-XX:PermSize和-XX:MaxPermSize来配置和解决问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

有时候程序会碰到java.lang.OutOfMemoryError,这个主要是JVM参数没有配好引起的。

OutOfMemoryError分两种:java.lang.OutOfMemoryError: Java heap space和java.lang.OutOfMemoryError: PermGen space。

前者是有关堆内存的内存溢出,可以通过配置-Xms和-Xmx参数来解决。

后者是有关非堆内存的内存溢出,可以通过配置-XX:PermSize和-XX:MaxPermSize来设置。

参数的含义

打开eclipse的eclipse.ini会看到如下参数:

-vmargs

-Xms128M

-Xmx512M

-XX:PermSize=64M

-XX:MaxPermSize=128M

-vmargs:用来说明后面的就是JVM的参数了

-Xms:JVM初始分配的堆内存

-Xmx:JVM最大允许分配的堆内存,按需分配

-XX:PermSize:JVM初始分配的非堆内存

-XX:MaxPermSize:JVM最大允许分配的非堆内存,按需分配

堆(Heap)内存和非堆(Non-Heap)内存

堆内存

JVM留给开发者用的内存。一般存放对象以及数组。

JVM初始分配的堆内存由-Xms指定,默认是物理内存的1/64;JVM最大分配的堆内存由-Xmx指定,默认是物理内存的1/4。

空余堆内存小于40%时,JVM就会增大堆内存直到-Xmx的最大限制;空余堆内存大于70%时,JVM会减少堆内存直到-Xms的最小限制。因此服务器一般设置-Xms、-Xmx相等以避免在每次GC后调整堆内存的大小。

如果-Xmx不指定或者指定偏小,应用可能会导致java.lang.OutOfMemory错误,此错误来自JVM,不是Throwable的,无法用try...catch捕捉。

非堆内存: 

JVM留给自己用的内存。方法区、JVM内部处理或优化所需的内存(如JIT编译后的代码缓存)、每个类结构(如运行时常数池、字段和方法数据)以及方法和构造方法的代码都在非堆内存中。

JVM初始分配的非堆内存由-XX:PermSize指定,默认是物理内存的1/64;JVM最大分配的非堆内存由-XX:MaxPermSize指定,默认是物理内存的1/4。(还有一说:MaxPermSize缺省值和-server -client选项相关,-server选项下默认MaxPermSize为64m,-client选项下默认MaxPermSize为32m)

-XX:MaxPermSize设置过小会导致java.lang.OutOfMemoryError: PermGen space,原因如下:

PermGen space用于存放Class和Meta的信息,GC不会对PermGen space进行处理,所以如果Load很多Class的话,就会出现上述Error。这种Error在web服务器对JSP进行pre compile的时候比较常见

### JVM 设置 Xmx 参数:最大堆内存 JVM 的 `-Xmx` 参数用于设置堆内存的最大值,是控制 Java 应用程序内存使用的关键配置之一。通过合理设置该参数,可以优化应用程序性能、减少垃圾回收(GC)频率,并避免内存溢出(OutOfMemoryError)。 #### 1. **-Xmx 参数的作用** `-Xmx` 指定的是 JVM 堆内存的最大可用空间。如果未显式设置,默认值通常为物理内存的 1/4 [^2]。例如: ```bash java -Xmx2g MyApp ``` 表示将堆内存的最大限制设置为 2GB。 在某些场景中,应用需要处理大量数据或并发请求,此时默认的堆内存可能不足以支撑运行需求,容易触发频繁的 Full GC 或直接抛出 `OutOfMemoryError`。因此,适当增加 `-Xmx` 可以缓解这些问题。 #### 2. **与 -Xms 配合使用的建议** 通常建议将 `-Xms`(初始堆大小)和 `-Xmx`(最大堆大小)设为相同值,这样可以避免 JVM 在运行时动态调整堆大小所带来的性能开销 [^1]。例如: ```bash java -Xms4g -Xmx4g MyApp ``` 在这种情况下,JVM启动时就分配了全部所需的堆内存,减少了运行时因堆扩容而导致的性能波动 [^3]。 此外,JVM 内部还存在一些隐式参数,如 `InitialHeapSize` 和 `MaxHeapSize`,它们分别对应 `-Xms` 和 `-Xmx` 的实际值 [^5]。 #### 3. **合理设置 -Xmx 的原则** 设置 `-Xmx` 时应遵循以下原则: - **不超过物理内存的可用空间**:设置过高的堆内存可能导致操作系统频繁交换内存(swap),从而影响性能。 - **考虑其他进程和系统资源**:除了 JVM 自身堆内存外,还需预留非堆内存(如元空间)、线程栈、Direct Buffer 等所需的空间。 - **结合监控工具分析**:可通过 `jmap`、`jstat`、`VisualVM` 或 MAT 工具进行内存分析,判断是否确实需要增大堆内存 [^4]。 #### 4. **查看当前 JVM 的堆设置** 可以通过如下命令查看 JVM 默认或实际生效的堆大小设置: ```bash java -XX:+PrintFlagsFinal -version | grep HeapSize ``` 输出示例: ``` uintx InitialHeapSize := 62914560 {product} uintx MaxHeapSize := 987758592 {product} ``` 其中 `InitialHeapSize` 对应 `-Xms`,`MaxHeapSize` 对应 `-Xmx` [^5]。 #### 5. **常见问题与调优策略** - **频繁 Full GC**:可能是堆内存不足,可尝试增加 `-Xmx`。 - **内存泄露风险**:即使设置了较大的堆内存,若对象无法被回收,最终仍会抛出 `OutOfMemoryError`。应使用内存分析工具定位泄漏源 [^4]。 - **堆内存过大导致停顿时间变长**:大堆内存虽然能容纳更多对象,但也会延长垃圾回收的暂停时间,需权衡取舍。 ---
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值