JVM调优

1.堆内存设置

-Xms 初始堆大小,ms是memory start的简称 ,等价于-XX:InitialHeapSize
-Xmx 最大堆大小,mx是memory max的简称 ,等价于参数-XX:MaxHeapSize

-Xms<heap size>[unit]
-Xmx<heap size>[unit]

例如:-Xmx2G -Xms800M
注意:在通常情况下,服务器项目在运行过程中,堆空间会不断的收缩与扩张,势必会造成不必要的系统压力。
所以在生产环境中,JVM的Xms和Xmx要设置成一样的,能够避免GC在调整堆大小带来的不必要的压力。

我们知道,Java8引入了元空间,而元空间使用的是本地内存而不是Java堆内存,其大小原则上取决于操作系统内存大小。因此元空间的大小并没有被Java8所定义,一旦它达到了全局限制,JVM就会自动增加它。 为了避免不确定的不稳定因素,我们也可以设置元空间大小

-XX:MaxMetaspaceSize=<metaspacesize>[unit]

根据oracle指南,在总可用内存之后,第二大的影响因素是年轻代(Young Generation)保留的堆比例,YG的默认最小大小是1310M,最大无限制。我们可以明确的分配:

-XX:NewSize=<young size>[unit]
-XX:MaxNewSize=<young size>[unit]

或者我们可以通过参数来设置新生代与老年代的比例

-XX:NewRatio=3 // 表示年轻代与年老代比值为1:3

2.垃圾收集器设置

  • 串行收集器(Serial Garbage Collector)
 -XX:+UseSerialGC

串行收集器是最简单的GC实现,使用单线程进行垃圾收集工作,并且在工作时会暂停其他所有工作线程,直到收集结束。是大多数没有小暂停时间要求并且在客户端上运行的应用程序的首选,但不适用于多线程应用,比如服务端环境。

  • 并行收集器(Parallel Garbage Collector)
    并行收集器是从Java5到Java8,JVM的默认收集器。它使用多线程进行垃圾收集,但也会在工作时暂停其他所有工作线程。如果我们使用这个收集器,可以指定最大的垃圾收集线程数、暂停时间、吞吐量和堆空间。
    启用命令:
-XX:+UseParallelGC

可选参数:
– 指定线程数:

-XX:ParallelGCThreads=<N>

– 期望的最大暂停时间(ms)

-XX:MacGCPauseMillis=<N>

– 最大吞吐量
进行垃圾收集的时间与不进行垃圾收集的时间的比例称为最大吞吐量目标。

-XX:GCTimeRatio=<N>
  • 并发收集器(Concurrent Mark Sweep Collector)
    CMS是老年代的重点收集器,使用的是标记-清除算法。其执行流程如下:
    初始标记:stop-the-world(std),虚拟机会停顿正在执行的任务,从垃圾回收的根对象开始,只扫描到能够和根对象关联的对象,并做标记,并不会耗时太多,很快就能完成。
    并发标记:并发追溯标记,程序不会停顿,该阶段紧随初始标记,会继续向下追溯标记,不会停止应用线程,两者并发执行
    并发预处理:查找执行并发标记阶段从年轻代晋升到老年代的对象,减少下一个阶段——重新标记的工作量(重新标记会暂停虚拟机)
    重新标记:暂停虚拟机,扫描CMS堆中的剩余对象。从跟对象开始一直向下追溯所有对象,比较耗时
    并发清理:清理垃圾对象,程序不会停顿
    并发重置:重置CMS收集器的数据结构
    在 CMS 垃圾收集器使用过程中,应用程序将暂停两次。这个收集器在 Java9 已过时,并在 Java14 中被移除。被G1收集器代替。

  • G1收集器(G1 Garbage Collector)
    G1收集器适用于运行在多线程大内存空间的应用,面向服务端的垃圾收集器,它是将Java堆内存划分为多个大小相等的独立区域(Region),并且跟踪这些区域里面的垃圾堆积程度,在后台维护一个优先列表,每次根据允许的收集时间,优先回收垃圾最多的区域(这就是Garbage First名称的来由)
    启用命令:

-XX:+UseG1GC

G1收集器已在JDK 1.7 u4版本正式投入使用

  • Z收集器(Z Garbage Collector)
    Z 垃圾收集器 (ZGC) 是 Oracle 在 JDK 11 中引入的一种创新垃圾收集算法。旨在最大限度地减少JVM上的应用程序暂停时间,使其特别适合需要低延迟和可伸缩的现代应用程序。ZGC 采用分代方式进行垃圾收集,将堆分为两代:年轻代和老年代(也称为成熟代)。年轻代又进一步分为Eden区和两个Survivor。老一代是长寿命对象最终被重新定位的地方。
    使用命令:
-XX: +UseZGC

扩展:新生代和老年代
新生代:大多数新创建的对象都会放在新生代中,但在某些情况下,对象也可能会直接放入老年代中,比如大对象,如果对象的大小超过了一定的阈值,该对象可能会直接分配到老年代中;比如大量对象,如果应用程序短时间内大量创建对象,导致Eden区无法容纳,那么一部分对象可能直接被分配到老年代。 新生代区域分为三个部分:Eden区和两个Survivor区(通常称作"from"和"to"或者"S1"和"S2")。被创建的对象会放在Eden区,当Eden区满了,会触发次级垃圾回收(minor garbage collection)。在这个过程中,垃圾收集器会识别和收集不可达对象,释放掉内存,而幸存的对象便会从Eden区转移到Survivor的一个区,然后清理Eden区。在几次minor GC之后幸存的对象,便会被升级为老年代。
老年代:老年代是长时间存活对象的储存区域。主垃圾回收(major garbage collection)的频率更低,但是会扫描和清理整个堆,包括新生代和老年代。主垃圾回收的目标是释放被对象长时间占用和不再需要的内存。

Stop-the-World:简称STW,指的是GC事件发生过程中,会产生所有应用程序的停顿。发生在:
– JVM由于要执行GC而停止应用程序的执行;
– 任何一种GC算法中都会发生
– 多数GC优化用减少Stop-the-world发生的时间来提高程序性能

3.垃圾回收日志信息(GC Logging)

-XX:+UseGCLogFileRotation	// 启用 GC 日志滚动
-XX:NummerOfGCLogFiles=<number of log files> // 日志时滚动使用的文件数
-XX:GCLogFileSize=<file size>[unit] // 定义日志文件的大小(日志将被轮换)
-Xloggc:/path/to/gc.log // 指定路径

4.处理OOM

请跳转文章:JAVA OOM问题

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值