JVM系列(五) -内存相关的调优参数

一、摘要

在上篇文章中,我们详细介绍了 JVM 的内存布局。

今天这篇文章,并结合之前的介绍知识,一起了解一下 JVM 内存相关的调优参数。

二、内存设置相关的命令

所有内存溢出的问题,除了代码可能存在问题以外,更直观的问题是内存空间不足,如何通过参数来控制各区域的内存大小呢?

我们先来看一张图。

相关的常用控制参数介绍!

2.1、堆内存大小相关参数设置

1)-Xms

设置堆的最小空间大小,此值必须是 1024 的倍数且大于 1 MB。附加字母 k 或 k 表示千字节,m 或 m 表示兆字节,g 或 g 表示千兆字节,其它命令参数同理。比如-Xms1024m,表示堆的最小内存为1024M,默认值为物理内存的1/64

2)-Xmx

设置堆的最大空间大小,此值必须是 1024 的倍数且大于 2 MB。比如-Xmx2048m,表示堆最大内存为2G,默认值为物理内存的1/4

对于服务器部署,-Xms-Xmx通常建议设置为相同的值,以避免堆的内存空间频繁扩缩。

3)-XX:+HeapDumpOnOutOfMemoryError

表示可以让虚拟机在出现内存溢出异常时 Dump 出当前的堆内存转储快照

2.2、年轻代内存大小相关参数设置

1)-XX:NewSize

设置年轻代的最小空间大小,比如-XX:NewSize=256m,表示年轻代的最小内存为256M

GC 在这个区域比在其他区域执行的频率更高,如果年轻一代的设置太小,那么将进行大量的小频率 GCs。如果设置太大,那么会执行完整的GCs,这可能需要很长时间才能完成。Oracle 建议将年轻一代的大小保持在堆总大小的一半到四分之一之间。同时,该值需要小于-Xms的值。

2)-XX:MaxNewSize

设置年轻代的最大空间大小,比如-XX:MaxNewSize=512m,表示年轻代的最大内存为512M

3)-Xmn

设置年轻代堆的初始大小和最大大小,比如-Xmn128m,表示年轻代的初始大小和最大大小为128M

这个参数是对-XX:newSize-XX:MaxnewSize两个参数同时进行配置,虽然会很方便,但需要注意的是这个参数是在 JDK1.4 版本以后才加入的,低于此版本无法使用。

没有直接设置老年代的参数,但是可以设置堆空间大小和年轻代空间大小两个参数来间接控制,公式如下:

老年代空间大小 = 堆空间大小 - 年轻代空间大小
2.3、比例方式相关参数设置

1)-XX:NewRatio

设置年轻代和老年代大小之间的比例,默认值是-XX:NewRatio=2,表示Young : Old = 1 : 2

2)-XX:SurvivorRatio

设置 Eden 空间大小和 Survivor 空间大小之间的比例,默认值是-XX:SurvivorRatio=8,表示Eden : from : to = 8 : 1 : 1

3)-XX:MinHeapFreeRatio

设置 GC 事件后允许的最小可用堆空间百分比(0到100),如果可用堆空间低于此值,则堆将被扩展。默认情况下,此参数为-XX:MinHeapFreeRatio=40,表示40%

4)-XX:MaxHeapFreeRatio

设置 GC 事件后允许的最大可用堆空间百分比(0到100)。如果可用堆空间高于此值,则堆将被缩小。默认情况下,此参数为-XX:MaxHeapFreeRatio=70,表示70%

2.4、非堆区相关参数设置

1)-XX:PermSize

设置永久代的最小空间大小,比如-XX:PermSize=256m,表示永久代的最小内存为256M,默认值为物理内存的1/64

2)-XX:MaxPermSize

置永久代的最大空间大小,比如-XX:MaxPermSize=512m,表示永久代的最大内存为512M,默认值为物理内存的1/4

值得注意的是,-XX:PermSize-XX:MaxPermSize这两个参数,在 JDK1.7 及以前的版本中有效,在 JDK1.8 中已经被弃用,被-XX:MetaspaceSize-XX:MaxMetaspaceSize两个参数取代。

2.5、栈内存相关参数设置

1)-Xss

设置每个线程的栈大小,比如-Xss1024k,表示每个线程的堆栈空间大小为1024KB,通常不需要我们调整设置,默认值取决于平台:

  • Linux/ARM (32-bit):320 KB
  • Linux/i386 (32-bit):320 KB
  • Linux/x64 (64-bit):1024 KB
  • OS X (64-bit):1024 KB
  • Oracle Solaris/i386 (32-bit):320 KB
  • Oracle Solaris/x64 (64-bit):1024 KB

2)-Xoss

设置每个线程中的本地方法栈大小,比如-Xoss128k,表示每个线程中的本地方法栈大小为128KB,不过 HotSpot 并不区分虚拟机栈和本地方法栈,因此对于 HotSpot 来说这个参数是无效的。

2.6、堆外内存相关参数设置

1)-XX:MaxDirectMemorySize

此参数的含义是通过Direct ByteBuffer方式分配的最大堆外内存大小。比如-XX:MaxDirectMemorySize=60m,表示堆外最大内存不能超过60M,如果没有设置,默认是 0,JVM 会自动申请内存的大小,最大大小受限于-Xmx值。

三、内存溢出的几种场景

在上文中,我们介绍了 JVM 内存结构以及可能会发生的异常状况,下面我们一起来复现一下几种常见的内存溢出现象。

3.1、堆溢出

堆溢出测试类如下。

/**
 * 虚拟机参数: -Xms10m -Xmx10m -XX:+HeapDumpOnOutOfMemoryError
 */
public class HeapOOMTest {
   

    public static void main(String[] args) {
   
        List<HeapOOMTest> list = new ArrayList<>();
        while (true){
   
            list.add(new HeapOOMTest());
        }
    }
}

在 IDEA 中设置 JVM 相关的参数。

运行后输出结果如下:

java.lang.OutOfMemoryError: Java heap space
Dumping heap to java_pid21886.hprof ...
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
	at java.util.Arrays.copyOf(Arrays.java:3210)
	at java.util.Arrays.copyOf(Arrays.java:3181)
	at java.util.ArrayList.grow(ArrayList.java:265)
	at java.util.ArrayList.ensureExplicitCapacity(ArrayList.java:239)
	at java.util.ArrayList
  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值