开发经验(三):堆栈内存设置Xms、Xmx、Permsize、MaxPermsize

516 阅读3分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

一、概念扫盲

弄明白Xms、Xmx、Permsize、MaxPermsize这几个名词的设置,就不得不先弄明白Java程序运行过程中的使用的内存是何物?如果我们把服务器(或者个人开发计算机)的物理内存比作一个大圆圈,如图:

image-20210901191216385

  • 蓝色部分为Java虚拟机未使用的物理内存,一般JVM内存的最大值与当前操作系统有很大关系,32位操作系统处理器的话,JVM的限制最大只有4G,如果操作系统为64位处理器的话,则没有这个限制。

  • 绿色部分为JVM使用内存中的非堆内存,有一种说法叫栈内存,存放基本类型数据存储,具有明确的生命周期,符合后进先出的原则,超出当前变量使用域后,进行销毁栈内存的使用,回收容量。还有一种说法,这部分包括两部分:静态存储区和栈存储两部分,静态存储策略主要存放具有定量周期的类对象变量。

  • 黄色部分为堆内存,应用运行过程中,存储new的对象实例以及引用类型数据,默认初始化大小为物理内存的1/64,最大容量为物理内容的1/4,默认空余堆内存小于40%的时候,JVM就会增大堆内存的容量直到设置的-Xmx的最大限制,超出之后就会报内存溢出。

    PS:

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

    -vmargs -Xms128M -Xmx512M -XX:PermSize=64M -XX:MaxPermSize=128M
    -vmargs 说明后面是VM的参数,所以后面的其实都是JVM的参数了
    -Xms128m JVM初始分配的堆内存
    -Xmx512m JVM最大允许分配的堆内存,按需分配
    -XX:PermSize=64M JVM初始分配的非堆内存
    -XX:MaxPermSize=128M JVM最大允许分配的非堆内存,按需分配
    

二、使用技巧

1)开发环境

日常开发过程中,各个Java应用的使用数据不会太多,可以将初始内存设置小一些 -Xms的值设置小一些,评估够用就可以。

2)生产环境

一般Java应用在生产环境部署的话,-Xms和-Xmx会设置为一样大小,如果不一样的话,JVM在堆内存使用过程中,会根据程序需要内存大于-Xms设置值的时候,将会分配更多的内存,且有可能需要移动一些objects和记账(book-keeping),这些动作都比较耗时,会使程序响应比较慢,极端情况下甚至会导致OOM。假如程序在闲时和忙时差别比较大,堆内存就会不停的进行伸缩。如果设置-Xms=-Xmx,就不会有这样的问题。

三、结论

在生产环境,设置-Xms和-Xmx相等以保证程序稳定。在开发测试环境,设置一个比较小的-Xms,以支撑更多的测试程序运行。

欢迎加入微信群,一起讨论交流 image-20220605052038635