JVM调优

本文内容

1 优化层面

2 JVM调优

1 优化层面

1.1 设计层面

系统的设计层面是要最先考虑的问题。一个糟糕的设计,会直接导致系统性能出现问题。

例如,对于支付宝和微信的红包系统,若设计出现问题,即便程序优秀、硬件强劲,也于事无补。反之,若设计良好,则事半功倍。

1.2 程序层面

在一个良好的设计下,程序本身的优劣就决定了性能的高低。高质量的代码会提高资源的利用率,减少不必要的操作,从而提升性能。

1.3 设置层面

排除设计和程序层面的原因,出现性能问题时,可以通过一些系统参数设置,以匹配现实情况,使得资源使用最优化,从而提升性能。

1.4 硬件层面

当上述三个层面都没有问题的时候,就要考虑扩展硬件设备了。

2 JVM调优(设置层面)

2.1 工作模式

2.1.1 client

占用内存小,启动速度快;

适合短时间运行。

2.1.2 server

与client模式相比,占用内存大,启动速度慢,但启动后,执行速度快;

适合长时间运行。

2.1.3 设置工作模式

配置文件:%JAVA_HOME%/jre/lib/amd64/jvm.cfg

单次启动:java -client/-server

2.2 堆内存

2.2.1 Max Memory

-Xmx    可用的最大内存数(Max Memory),即JVM可占用的内存上限。

通常,服务器是专机专用,除了运行指定的服务程序,一般情况下,不会同时运行其它的程序。

所以,预留部分内存给操作系统、元空间内存、线程内存等,其余内存尽可能分配给JVM,以提高内存利用率和性能。

2.2.2 Total Memory & Virtual Memory

-Xms    初始分配内存(Total Memory)。

其余作为伸缩区(Virtual Memory),即 Max Memory = Total Memory + Virtual Memory。

当初始分配的内存不足时,会从伸缩区申请部分内存,当可用内存充裕时,再将申请来的内存释放。

通常,服务器是专机专用,除了运行执行的服务程序,不会同时运行其它的程序。

所以,一般会将Total Memory设置与Max Memory相等,即不设置伸缩区,以减少从伸缩区申请和释放内存带来的开销。

2.2.3 Young Memory (Eden + Survivor) &Tenured Memory

-Xmn    年轻代内存(Young Memory)

-XX:NewRatio=n    年轻代与老年代的内存比率(Young:Tenured = 1:n)

-XX:NewSize=n    存活代内存(Survivor Memory)

-XX:SurvivorRatio=n    存活代与伊甸园的内存比率(Survivor:Eden = 1:n)

-XX:PretenureSizeThreshold=n    直接晋升老年代的对象大小

-XX:MaxTenuringThreshold=n    存活代最大年龄(经历n次GC还存活的内存对象将晋升至老年代)

-XX:+UseAdaptiveSizePolicy    是否采用动态控制策略(堆中各区域大小及晋升老年代的年龄)

新创建的对象都会保存在Young Memory的Eden Memory中,满足一定条件的对象会被移至Young Memory的Survivor Memory中,进而再晋级至Tenured Memory中。

因此,需要根据程序实际运行情况,合理设置相应内存数值和比率。

2.3 线程内存

-Xss    每个线程分配的内存,JDK 5.0以后,每个线程内存大小默认为1M。

线程内存占用本机物理内存,而非JVM堆内存。

降低单个线程的内存,可以提高可并发的线程数量,但是,线程数量有一定限制(上限),不能无限上涨。

应合理设置线程堆栈内存,通常,将线程数控制在3000-5000范围内。

2.4 元空间内存

-XX:MaxMetaspaceSize    最大容量,默认无限制(受到本机物理内存限制)

-XX:MetaspaceSize    初始分配容量

-XX:MinMetaspaceFreeRatio    执行GC后,最小剩余元空间比例。

-XX:MaxMetaspaceFreeRatio    执行GC后,最大剩余元空间比例。

2.5 回收机制

-XX:+UseSerialGC    年轻代:串行、复制算法,适合单CPU环境Client模式,老年代支持CMS;

-XX:+UseParNewGC    年轻代:并行、复制算法,适合多CPU环境Server模式,老年代支持CMS;

-XX:+UseParallelGC    年轻代:并行、复制算法,适合后台运算而无太多交互任务情况,老年代仅支持Serial Old收集器;

-XX:+UseParalledlOldGC    老年代:并行、标记-整理算法,适合后台运算而无太多交互任务情况;

-XX:ParallelGCThreads=n    设置并行收集器使用的CPU数量;

-XX:+UseConcMarkSweepGC    老年代:并发、标记-清除算法,适合服务端应用;

-XX:+CMSParallelRemarkEnabled    开启并行Remark模式(减少Remark阶段暂停时间);

-XX:+CMSScavengeBeforeRemark    每次Remark之前,先进行一次Minor GC(减少Remark阶段暂停时间);

-XX:+UseCMSInitiatingOccupancyOnly    仅当内存使用情况达到指定阈值时,才进行CMS操作;

-XX:CMSInitiatingOccupancyFraction=n    指定CMS操作执行判断的内存阈值;

-XX:+CMSIncrementalMode    设置为增量模式,适用于单CPU情况;

-XX:+UseG1GC    年轻代+老年代:并发、年轻代复制/老年代标记-整理,适合服务端应用;

-XX:MaxGCPauseMillis=n    设置最大暂停时间目标(毫秒),JVM会尽量达到该目标,但不保证一定能达到目标;

-XX:+ScavengeBeforeFullGC    每次Full GC之前,先执行一次Minor GC(减少Full GC暂停时间)

-XX:+DisableExplicitGC    关闭显示执行GC代码功能(禁用System.gc()方法)

2.6 统计信息

2.6.1 GC

-Xloggc:/data/log/gc.log    指定GC日志文件路径

-XX:+UseGCLogFileRotation    开启GC滚动日志

-XX:GCLogFileSize=n    指定GC滚动日志文件大小

-XX:NumberOfGCLogFiles=n    指定GC滚动日志文件数量

-XX:+PrintGC    每次触发GC的时候打印相关日志(在JDK9中已经弃用)

-XX:+PrintGCDetails    更详细的GC日志

-XX:+PrintGCDateStamps    打印日期和时间信息

-XX:+PrintGCTimeStamps    打印启动时长信息(自JVM启动起计时)

-XX:+PrintHeapAtGC    每次GC时打印堆的详细详细信息

-XX:+PrintGCApplicationConcurrentTime    打印应用程序执行时间

-XX:+PrintGCApplicationAtoppedTime    打印应用程序由GC引起的停顿时间

-XX:+PrintReferenceGC    跟踪系统内的软引用,弱引用,虚引用和finallize队列。

2.6.2 类跟踪

-verbose:class    跟踪类的加载和卸载(-verbose:gc 相当于 -XX:+PrintGC)

-XX:+TraceClassLoading    单独跟踪类加载

-XX:+TraceClassUnloading    单独跟踪类卸载

-XX:+PrintClassHistogram    查看运行时类的分布情况

2.7 分析工具

2.7.1 jstat

jstat (Java Virtual Machine statistics monitoring tool) 是JDK自带的一个轻量级分析工具。

可通过 jstat 对GC情况进行打印输出和分析,常用格式:

jstat -gcutil <PID> [interval [limit]]

  • <PID> 表示JVM进程ID,可通过 ps -ef | grep java 查询
  • interval 表示打印间隔时间(毫秒)
  • limit 表示打印次数(缺省表示无限打印)

例如:

jstat -gcutil 17 1000

每1000毫秒打印一次进程ID为17的JVM内存情况

2.7.2 jstack

jstack 是JDK自带的线程堆栈分析工具。

可通过 jstack 查看或导出 Java 应用程序中线程堆栈信息,常用格式:

jstack <PID>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值