分享

生产平台必须设置的几个JVM参数,你设置了吗?

 北欧模式 2022-06-21 发布于陕西

对于JVM参数,大多数JAVA程序员都是只略知皮毛而已,甚至很多人压根就没配置过JVM参数,少部分人会配置一些内存相关的参数。很多人并没有手动配置JVM参数的意识,甚至一些略有经验的码农也认为只需要使用默认的JVM参数就好了。事情真的是这样的吗?那显然不是的,不同的JVM参数配置会有效的增加工作效率,减轻工作量,所以作为一名资深JAVA程序员,一定要养成针对环境特点配置JVM参数的好习惯。

那么我们来看看,哪些JVM参数应该在生产平台上配置吧。

一、HeapDumpOnOutOfMemoryError

在生产平台上,HeapDumpOnOutOfMemoryError是必须要配置的重要参数之一。它的作用是当堆抛出OOM错误时,dump出当前的内存堆存储快照。因为生产平台不同于测试环境,复现生产平台场景的成本非常高,甚至对于一些小公司来说,其成本并非公司所能承受。因此,在生产平台出现OOM错误时,保留现场的内存堆快照,对于定位问题,快速解决问题,具有极其重要的意义。

二、GC相关内存配置

jdk18以前,通常在生产环境要配置一下-XX:PermSize-XX:MaxPermSize,表示在JVM里存储Java类信息,常量池和静态变量的永久代(方法区) 区域初始值和最大值。在项目启动后,这个值是固定的,如果项目 class(类实例) 过多,很可能会导致OutOfMemoryError: PermGen异常。

而在jdk18及以后,关于永久代的配置已经成为了-XX:MetaspaceSizeXX:MaxMetaspaceSizeMetaspaceSize如果不做配置,默认大小约21M,而MaxMetaspaceSize最大元空间则只受本地内存大小限制。MetaspaceSize触发FullGC的阈值,默认约为21M,如做了配置,最小阈值为自定义配置大小。空间使用达到阈值,触发FullGC,同时对该值扩大。当然如果元空间实际使用小于阈值,在GC的时候也会对该值缩小。

MaxMetaspaceSize为元空间的最大值,如果设置太小,可能会导致频繁FullGC,甚至OOM

三、AutoBoxCacheMax

JAVA进程启动的时候会加载rtjar这个核心包rtjar包里的Integer也同时被加载到JVMInteger里面有一个IntegerCache缓存。其中有一个静态代码块,JVM在加载Integer这个类时,会优先加载静态的代码。当JVM进程启动完毕后,-128 ~ +127 范围的数字会被缓存起来,调用valueOf方法的时候,如果是这个范围内的数字,,则直接从缓存取出。超过这个范围的,就只能构造新的Integer对象了。而利用AutoBoxCacheMax这个参数,可以修改这个缓存值,因此,如果项目中需要经常对更大的整数类型进行转换的话,那么就可以将这个参数修改得更大些,比如说设置成20000

四、AlwaysPreTouch

JAVA进程启动的时候虽然我们可以为JVM指定合适的内存大小但是这些内存操作系统并没有真正的分配给JVM而是等JVM访问这些内存的时候才真正分配这样会造成以下问题

1GC的时候新生代的对象要晋升到老年代的时候需要内存这个时候操作系统才真正分配内存这样就会加大young gc的停顿时间;

2、可能存在内存碎片的问题。

因此,可以在JVM启动的时候配置AlwaysPreTouch参数,这样JVM就会让操作系统把内存真正的分配给JVM。后续JVM就可以顺畅的访问内存了。

五、MaxTenuringThreshold

MaxTenuringThreshold年轻代晋升老年代的最大年龄阈值。CMS垃圾回收机制中默认为6,其它垃圾回收算法里默认是15。并且该参数值设置之后只是初始值会动态改变。在GC回收的时候。当Eden区满了的时候,会触发第一次GC,把还活着的对象拷贝到SurvivorFrom区,当Eden区再次触发GC的时候,会扫描EdenSurvivorFrom区,对这两个区域进行垃圾回收,经过这次回收还活着的对象,会从From区复制到SurvivorTo区,同时把这些对象的年龄加1,当年龄达到了老年代的标准,就是上面所说的156,则复制到老年代去。注意FromTo只是两个临时存储点,在不同的GC阶段是会互换的。

如果将MaxTenuringThreshold设置为0,则年轻对象不会经过Survivor区,直接进入老年代。由于新生代使用copy算法,如果Survivor区存活的对象太久的话,Survivor区存活的对象就越多,这个就会影响copy算法的性能,使得young gc停顿的时间加长,因此可以依据自己的生产环境,来设置这个值。

最后,大家一定还要熟练使用jinfo这个命令来查看jvm的配置参数哦。

    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多