JVM调优由浅到深(四)——JVM内存分配参数详解

我们在这一篇文章中已经大概了解到了jvm的参数有哪些,大概怎么设置。
JVM调优由浅到深(一)——jvm参数配置

现在我们再来详细得再更加详细分析一次;

常用参数设置

设置最大堆内存

参数说明例子
最大堆内存-Xmx10m

在运行时,可以使用 Runtime.getRuntime().maxMemory() 取得系统可用的最大堆内存。

    public void test5(){
        System.out.println(Runtime.getRuntime().maxMemory()/1024/1024);
    }

运行结果:

设置最小堆内存

参数说明例子
最小堆内存-Xms10m

Java应用程序在运行时,首先被分配-Xms指定的内存大小,并尽可能尝试在这个空间段内运行程序。
当-Xms指定的内存大小确实无法满足应用程序时,JVM 才会向操作系统申请更多的内存,直到内存大小达到-Xmx指定的最大内存为止。
若超过-Xmx的值,则抛出 OutOfMemoryError 异常。

如果 -Xms 的数值较小,那么JVM为了保证系统尽可能地在指定内存范围内运行,就会更加频繁地进行GC操作,以释放失效的内存空间。
从而,会增加 Minor GC 和 Full GC的次数,对系统性能产生一定的影响
因此把 -Xms 值设置为 -Xmx 时,可以在系统运行初期减少 GC 的次数和耗时。

设置新生代

参数说明例子
新生代-Xmn2m

设置一个较大的新生代会减少老年代的大小,这个参数对系统性能以及 GC 行为有很大的影响。
新生代的大小一般设置为整个堆空间的1/4到1/3左右。

在 Hot Spot 虚拟机中,-XX:NewSize 用于设置新生代的初始大小,
-XX:MaxNewSize用于设置新生代的最大值。
但通常情况下,只设置 -Xmn 以及可以满足绝大部分应用的需要。
设置 -Xmn 的效果等同于设置了相同的-XX:NewSize 和 -XX:MaxNewSize。

若设置不同的-XX:NewSize 和 -XX:MaxNewSize可能会导致内存震荡,从而产生不必要的系统开销。

设置持久代

持久代(方法区)不属于Java堆的一部分。在Hot Spot虚拟机中,使用-XX:MaxPermSize可以设置持久代的最大值,使用-XX:PermSize可以设置持久代的初始大小。

JDK1.8取消了PermGen,取而代之的是Metaspace(元空间),
所以PermSize和MaxPermSize参数失效,取而代之的是 -XX:MetaspaceSize
和 -XX:MaxMetaspaceSize。

参数说明例子
持久代的初始大小-XX:MetaspaceSize=64M
持久代的最大值-XX:MaxMetaspaceSize=128M

持久代的大小直接决定了系统可以支持多少个类定义和多少常量。
对于使用 CGLIB 或者 Javassist 等动态字节码生成工具的应用程序而言,
设置合理的持久代大小有助于维持系统稳定。

一般来说,设置MaxMetaspaceSize为64MB已经可以满足绝大部分应用程序正常工作。
如果依然出现永久区溢出,可以将MaxMetaspaceSize设置为128MB。
这是两个很常用的永久区取值。

设置线程栈

线程栈是线程的一块私有空间。有关描述可以参考前文的“Java虚拟机栈”。

参数说明例子
线程栈大小-Xss1M

在线程中进行局部变量分配,函数调用时,都需要在栈中开辟空间。

如果栈的空间分配太小,那么线程在运行时,可能没有足够的空间分配局部变量或者达不到足够的函数调用深度,导致程序异常退出;

如果栈空间过大,那么开设线程所需的内存成本就会上升,系统所能支持的线程总数就会下降。

由于Java堆也是向操作系统申请内存空间的,
因此,如果堆空间过大,就会导致操作系统可用于线程栈的内存减少,
从而间接减少程序所能支持的线程数量。

当系统由于内存不够无法创建新的线程时,会抛出 OOM 异常如下:

java.lang.OutOfMemoryError: unable to create new native thread

根据以上内容可知,这并不是由于堆内存不够而导致的 OOM,而是因为操作系统内存减去堆内存后,剩余的系统内存不足而无法创建新的线程。

在这种情况下,可以尝试减少堆内存,以换取更多的系统空间,来解决这个问题。

如果系统确实需要大量的线程并发执行,那么设置一个较小的堆和较小的栈,
有助于提供系统所能承受的最大线程数。

堆的内存分配

参数说明例子
eden区/survivor区-XX:SurvivorRatio=8
老年代/新生代-XX:NewRatio=2

参数 -XX:SurvivorRatio 是用来设置新生代中,eden空间和s0空间的比例关系。
s0 和 s1 空间又被称为 from 空间和 to 空间。
它们的大小是相同的,职能也是一样的,并在 Minor GC后,会互换角色。

公式:-XX:SurvivorRatio = eden/s0 = eden/s1

举例:当设置JVM参数 -Xmn10M -XX:SurvivorRatio=8 就等于设置 eden=8M,s0=1M,s1=1M。

参数 -XX:NewRatio 是用来设置新生代与老年代的比例:

公式:-XX:NewRatio = 老年代 / 新生代

举例:当设置JVM参数 -Xms18M -Xmx18M -XX:NewRatio=2运行程序时,新生代约占6MB,老年代约占12MB。

堆分配参数总结

参数说明例子
-Xmx设置Java应用程序能获得的最大堆
-Xms设置Java应用程序启动时的初始堆
-Xss设置新生代的初始大小与最大值
-Xmn设置新生代的初始大小与最大值
-XX:NewSize设置新生代的大小。
-XX:NewRatio设置老年代与新生代的比例,它等于老年代大小除以新生代大小。
-XX:SurvivorRatio设置新生代中eden区和survivor区的比例
-XX:MetaspaceSizeXX
-XX:MetaspaceSize(Java8)设置永久区的初始值。。
-XX:MaxMetaspaceSize(Java8)最大的持久区大小。
-XX:MinHeapFreeRatio设置堆空间的最大空闲比例,当堆空间的空闲内存小于这个数值时,JVM便会扩展堆空间
-XX:MaxHeapFreeRatio设置堆空间的最大空闲比例。当堆空间的空闲内存大于这个数值时,便会压缩堆空间,得到一个较小的堆。
-XX:TargetSurvivorRatio设置survivor区的可使用率。当survivor区的空间使用率达到这个值时,会将对象送入老年代。

非常感谢以下博主的优秀博客

https://www.cnblogs.com/yueshutong/p/9768298.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值