您的位置 首页 java

Java-JVM调优

基础概念

  • 一般 JVM 调优,重点在于调整JVM堆大小、调整垃圾回收器
  • jvm调优的目的是,减少full gc、降低gc停顿时间、提高吞吐量;调优的顺序=“提高吞吐量”>“降低gc停顿时间”;在满足吞吐量的前提下,再降低gc停顿时间;若不能同时满足以上,则选择最适合系统的一种调优结果

JVM调优常用参数

  • -Xmx1024m:最大堆内存,当物理内存不超过192m时最大堆内存为物理内存的一半,否则为物理内存的四分一
  • -Xms1024m:最小堆内存,一般设置为与-Xmx同等值
  • -XX:+PrintGCDetails:输出gc详细日志
  • -XX:+PrintGCTimeStamps或-XX:+PrintGCDateStamps:输出gc信息时带上时间戳
  • jcmd:专用于查看JVM状态,可以查看正在运行的进程,会显示出进程号
  • jmap -heap 10864:查看进程号为10864的进程的堆使用情况

具体参数如下:

 F:Iwebappdemo-test>jmap -heap 10864
Attaching to process ID 10864, please wait...
Debugger attached successfully.
 Server  compiler detected.
JVM version is 25.65-b01

using thread-local object allocation.
Parallel GC with 4 thread(s)

Heap Configuration:
   MinHeapFreeRatio         = 0   //空余堆内存最小百分比,HeapFreeRatio=空闲堆内存的百分比=现有空闲堆内存/总共对内存*100,当MinHeapFreeRatio<HeapFreeRatio时,在每次垃圾回收之后需要进行对扩容
   MaxHeapFreeRatio         = 100 //空余堆内存最大百分比
   MaxHeapSize              = 1044381696 (996.0MB)  //996.0MB=最大堆内存无物理内存1/4=4G*1/4约等于1G
   NewSize                  = 22020096 (21.0MB)  //年轻代堆内存的初始大小
   MaxNewSize               = 348127232 (332.0MB)  //年轻代堆内存的允许最大值,因为年轻代:老年代=1:2,所以年轻代最大=996*1/3=332
   OldSize                  = 45088768 (43.0MB)
   NewRatio                 = 2  //老年代:年轻代=2:1
   SurvivorRatio            = 8  //年轻代中Eden区:Survivor区=8:2,Survivor区=SurvivorFrom区+SurvivorTo区=1+1=2
   MetaspaceSize            = 21807104 (20.796875MB)  //jdk1.8之后使用的元空间默认大小
   CompressedClassSpaceSize = 1073741824 (1024.0MB)
   MaxMetaspaceSize         = 17592186044415 MB //jdk1.8之后使用的元空间的最大值
   G1HeapRegionSize         = 0 (0.0MB)  //若使用G1垃圾回收器,JVM把堆内存每个多个大小相等的区域,指定每个区域的大小

Heap Usage:
PS Young Generation
Eden Space:  //年轻代的使用情况
   capacity = 289931264 (276.5MB)
   used     = 160612016 (153.1715545654297MB)
   free     = 129319248 (123.32844543457031MB)
   55.39658392963099% used
From Space:  //SurvivorFrom区的使用情况
   capacity = 5767168 (5.5MB)
   used     = 65536 (0.0625MB)
   free     = 5701632 (5.4375MB)
   1.1363636363636365% used
To Space:  //SurvivorTo区的使用情况
   capacity = 5242880 (5.0MB)
   used     = 0 (0.0MB)
   free     = 5242880 (5.0MB)
   0.0% used
PS Old Generation   //老年代的使用情况
   capacity = 37748736 (36.0MB)
   used     = 13700064 (13.065399169921875MB)
   free     = 24048672 (22.934600830078125MB)
   36.29277547200521% used

  

监控JVM

实战源码:以demo-test工程为例,用gcviewner和 jdk 内置的监控jvm命令来做jvm调优

 package com.example.demo;
import com.example.util. Thread Test;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoTestApplication {

    public  static   void  main(String[] args) {
        SpringApplication.run(DemoTestApplication.class, args);
        ThreadTest.testJVM();
    }

}

public class ThreadTest {

    public static void main(String[] args) {
        testJVM();
    }

    public static void testJVM(){
        //匿名内部类重写Runnable的run方法可以写成箭头函数:()->{run方法的内容}
        //1000ms后每50ms执行创建1个 线程 ,每个线程150*512*1024 byte =150*512*1024B=150*512k=150*0.5M=75M,1s内最多1000/50=20个线程,则1s内最大占用内存=75*20=150M
        Executors.newScheduledThreadPool(1).scheduleAtFixedRate(()->{
            new Thread(()->{
                for(int i=1;i<=150;i++){
                    byte[] b=new byte[1024*512];//0.5M
                }
                System.out.println(Thread.currentThread().getName()+"已分配512k内存...");
            }).start();
        },1000,50,TimeUnit.MILLISECONDS);
    }


  

在target目录下【java -jar -Xloggc:gc.log -Xmx35m -Xms35m -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps demo-test.jar】启动jar包或者直接在idea中添加【-Xloggc:gc.log -Xmx35m -Xms35m -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps】启动springboot启动类,以下用gcviewner监控JVM :

  • gcviwner

gcviwner是一款可以监控GC日志的工具,前提是要拿到gc日志,gcviwner用法可参考【】 ,命令 【java -jar gcviewer-1.37-SNAPSHOT.jar】启动gcviwner,并导入gc.log日志,如下,

Java-JVM调优

Java-JVM调优

Java-JVM调优

上中下三张图,由上图可知吞吐量为74.26%,一般可以达到90%以上,红线是堆的实时总内存,蓝线是堆的实时已使用内存,灰色为young gc,黑色为full gc,可知灰色的线太密集=young gc频繁,黑色的线也是太密集=full gc频繁;full gc总数为296,一般可以把full gc降到个位数;

由中图可知最大停顿时间比较大,达到了892ms,一般可调优到几十毫秒级别;

有下图可看到young gc和full gc的情况,full gc次数296,比较频繁;同时元空间metadata区域过小,可以适当调大

由上,把metadata调为64M,执行【java -jar -XX:MetaspaceSize=64m -Xloggc:gc.log -Xmx35m -Xms35m -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps demo-test.jar】重新启动jar包:

可知full gc次数还是比较多、最大停顿时间也比较长、吞吐量也低,尝试着增大’最大堆内存’,执行【java -jar -XX:MetaspaceSize=64m -Xloggc:gc.log -Xmx100m -Xms100m -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps demo-test.jar】重新启动jar包:

可知full gc次数变少了(黑线少了,0次)、最大停顿时间也短了(94.65ms,到了十几毫秒级别)、吞吐量也高了(93.83%)

至此,调优基本满足上面的【减少full gc、降低gc停顿时间、提高吞吐量】的要求。

下面是jdk内置的jvm监控命令

  • jstat命令

jstat命令用于监视 虚拟机 的运行状态,命令格式【jstat -参数命令 进程号 间隔毫秒数 总输出次数】,主要参数项:

 //每1000ms统计一次demo-test-0.0.1.jar的gc信息
jstat -gc $(jcmd | grep "demo-test-0.0.1.jar" | awk '{print $1}') 1000
  
Java-JVM调优


S0C、S1C、S0U、S1U:C是总量,U是使用量,代表S0(survivorFrom区)和S1(survivorTo区)的总量与使用量

EC、EU:Eden区总量与使用量

OC、OU:Old区总量与使用量

MC、MU: Metaspace区(元空间)总量与使用量

YGC、YGCT:young gc的次数与时间

FGC、FGCT:full gc的次数与时间<

GCT:总的GC时间

 //每1000ms统计一次进程ID为10492的gc信息,共统计10次数结束统计
jstat -gc 10492 10
  

  • jps

jps可以查看正在运行的 java 进程,命令格式【 jsp 参数】,主要参数项:

 【jsp -l】查看具体的包名
  

  • jinfo

可以查看启动 jar 包时未显式指定的系统默认值,以及动态修改这些默认值,命令格式【jinfo -flag 默认的参数 进程id】,查看【年轻代:老年代】的内存比例:

  • jmap

jmap查看java内存信息,命令格式【jmap -参数 进程id】,参数项:

 实例如上:【jmap -heap 10864】查看进程号为10864的进程的堆使用情况
  
  • jstack

jstack是一个非常有用的命令,可以查看正在运行的线程的堆栈信息,比如查看后天没有相应的线程在做些什么,在等待什么资源,命令格式【jstack 参数项 进程号】,主要参数项如下:

 //查看进程的堆栈及锁的信息
jstack -l 10220
  
Java-JVM调优


图中线程状态是很重要的一个要素:

Java-JVM调优

CMS收集器和G1收集器的调优

启动各种垃圾收集器

参数

说明

-XX:+UseParallelGC

新生代使用并行回收收集器

-XX:+Use ParalleloldGC

老年代使用并行回收收集器

-XX:ParallelGCThreads

设置用于垃圾回收的线程数

-XX:+UseAdaptiveSizePolicy

打开自适应GC策略

CMS和G1的调优

  • cms是分代收集算法中老年代的算法(用标记整理算法),G1却适用于年轻代和老年代,故G1可以采用复制算法不会导致内存碎片,而cms不能采用年轻代的复制算法而导致有内存碎片
  • G1是由一个个区域块组成的,即使有碎片也只会影响某个区域块,不会影响整个堆
  • cms采用老年代标记整理算法,需要扫描整个表来标记整理,故存在停顿(即使它是并发);G1的停顿取决于需要收集的’区域块’个数,而不用等整个堆空间,所以g1的停顿时间比cms少

私信666领取资料

文章来源:智云一二三科技

文章标题:Java-JVM调优

文章地址:https://www.zhihuclub.com/186305.shtml

关于作者: 智云科技

热门文章

网站地图