当前位置:   article > 正文

JVM调优面试题——参数命令专题_面试题 常用的jvm调优的参数都有哪些

面试题 常用的jvm调优的参数都有哪些

在这里插入图片描述

1、JVM参数有哪些?

1.1、 标准参数

-version
-help
-server
-cp
  • 1
  • 2
  • 3
  • 4

image.png

1.2、-X参数

-Xint     解释执行
-Xcomp    第一次使用就编译成本地代码
-Xmixed   混合模式,JVM自己来决定
  • 1
  • 2
  • 3

image.png

1.3、 -XX参数

使用得最多的参数类型,主要用于JVM调优和Debug

a.Boolean类型
格式:-XX:[+-]<name>            +或-表示启用或者禁用name属性
比如:-XX:+UseConcMarkSweepGC   表示启用CMS类型的垃圾回收器
	 -XX:+UseG1GC              表示启用G1类型的垃圾回收器
b.非Boolean类型
格式:-XX<name>=<value>表示name属性的值是value
比如:-XX:MaxGCPauseMillis=500   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

1.4、 其他参数

这块也相当于是-XX类型的参数

-Xms1000M等价于-XX:InitialHeapSize=1000M
-Xmx1000M等价于-XX:MaxHeapSize=1000M
-Xss100等价于-XX:ThreadStackSize=100
  • 1
  • 2
  • 3

1.5、 查看参数

 java -XX:+PrintFlagsFinal -version > flags.txt
  • 1

image.png
image.png

值得注意的是"=“表示默认值,”:="表示被用户或JVM修改后的值
一般要设置参数,可以先查看一下当前参数是什么,然后进行修改

1.6、 设置参数的常见方式

  • 开发工具中设置比如IDEA,eclipse
  • 运行jar包的时候:java -XX:+UseG1GC xxx.jar
  • web容器比如tomcat,可以在脚本中的进行设置
  • 通过jinfo实时调整某个java进程的参数(参数只有被标记为manageable的flags可以被实时修改)

1.7、 常用参数含义

参数含义说明
-XX:CICompilerCount=3最大并行编译数如果设置大于1,虽然编译速度会提高,但是同样影响系统稳定性,会增加JVM崩溃的可能
-XX:InitialHeapSize=100M初始化堆大小简写-Xms100M
-XX:MaxHeapSize=100M最大堆大小简写-Xms100M
-XX:NewSize=20M设置年轻代的大小
-XX:MaxNewSize=50M年轻代最大大小
-XX:OldSize=50M设置老年代大小
-XX:MetaspaceSize=50M设置方法区大小
-XX:MaxMetaspaceSize=50M方法区最大大小
-XX:+UseParallelGC使用UseParallelGC新生代,吞吐量优先
-XX:+UseParallelOldGC使用UseParallelOldGC老年代,吞吐量优先
-XX:+UseConcMarkSweepGC使用CMS老年代,停顿时间优先
-XX:+UseG1GC使用G1GC新生代,老年代,停顿时间优先
-XX:NewRatio新老生代的比值比如-XX:Ratio=4,则表示新生代:老年代=1:4,也就是新生代占整个堆内存的1/5
-XX:SurvivorRatio两个S区和Eden区的比值比如-XX:SurvivorRatio=8,也就是(S0+S1):Eden=2:8,也就是一个S占整个新生代的1/10
-XX:+HeapDumpOnOutOfMemoryError启动堆内存溢出打印当JVM堆内存发生溢出时,也就是OOM,自动生成dump文件
-XX:HeapDumpPath=heap.hprof指定堆内存溢出打印目录表示在当前目录生成一个heap.hprof文件
-XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -Xloggc:g1-gc.log打印出GC日志可以使用不同的垃圾收集器,对比查看GC情况
-Xss128k设置每个线程的堆栈大小经验值是3000-5000最佳
-XX:MaxTenuringThreshold=6提升年老代的最大临界值默认值为 15
-XX:InitiatingHeapOccupancyPercent启动并发GC周期时堆内存使用占比G1之类的垃圾收集器用它来触发并发GC周期,基于整个堆的使用率,而不只是某一代内存的使用比. 值为 0 则表示”一直执行GC循环”. 默认值为 45.
-XX:G1HeapWastePercent允许的浪费堆空间的占比默认是10%,如果并发标记可回收的空间小于10%,则不会触发MixedGC。
-XX:MaxGCPauseMillis=200msG1最大停顿时间暂停时间不能太小,太小的话就会导致出现G1跟不上垃圾产生的速度。最终退化成Full GC。所以对这个参数的调优是一个持续的过程,逐步调整到最佳状态。
-XX:ConcGCThreads=n并发垃圾收集器使用的线程数量默认值随JVM运行的平台不同而不同
-XX:G1MixedGCLiveThresholdPercent=65混合垃圾回收周期中要包括的旧区域设置占用率阈值默认占用率为 65%
-XX:G1MixedGCCountTarget=8设置标记周期完成后,对存活数据上限为 G1MixedGCLIveThresholdPercent 的旧区域执行混合垃圾回收的目标次数默认8次混合垃圾回收,混合回收的目标是要控制在此目标次数以内
-XX:G1OldCSetRegionThresholdPercent=1描述Mixed GC时,Old Region被加入到CSet中默认情况下,G1只把10%的Old Region加入到CSet中

2、JVM常用命令有哪些?

2.1、jps

查看java进程

image.png

2.2、jinfo

实时查看和调整JVM配置参数

# 查看某个java进程属性的值
jinfo -flag MaxHeapSize PID 
jinfo -flag UseG1GC PID
  • 1
  • 2
  • 3

image.png

# 参数只有被标记为manageable的flags可以被实时修改
jinfo -flag [+|-] PID
jinfo -flag <name>=<value> PID
  • 1
  • 2
  • 3
# 查看曾经赋过值的一些参数
jinfo -flags PID
  • 1
  • 2

image.png

2.3、jstat

查看虚拟机性能统计信息

# 查看类装载信息 每1000毫秒输出一次,共输出10次
jstat -class PID 1000 10 
  • 1
  • 2

image.png

# 查看垃圾收集信息
jstat -gc PID 1000 10
  • 1
  • 2

image.png

2.4、jstack

查看线程堆栈信息

jstack PID
  • 1

image.png

排查死锁案例

//运行主类
public class DeadLockDemo
{
    public static void main(String[] args)
    {
        DeadLock d1=new DeadLock(true);
        DeadLock d2=new DeadLock(false);
        Thread t1=new Thread(d1);
        Thread t2=new Thread(d2);
        t1.start();
        t2.start();
    }
}
//定义锁对象
class MyLock{
    public static Object obj1=new Object();
    public static Object obj2=new Object();
}
//死锁代码
class DeadLock implements Runnable{
    private boolean flag;
    DeadLock(boolean flag){
        this.flag=flag;
    }
    public void run() {
        if(flag) {
            while(true) {
                synchronized(MyLock.obj1) {
                    System.out.println(Thread.currentThread().getName()+"----if获得obj1锁");
                    synchronized(MyLock.obj2) {
                        System.out.println(Thread.currentThread().getName()+"----if获得obj2锁");
                    }
                }
            }
        }
        else {
            while(true){
                synchronized(MyLock.obj2) {
                    System.out.println(Thread.currentThread().getName()+"----否则获得obj2锁");
                    synchronized(MyLock.obj1) {
                        System.out.println(Thread.currentThread().getName()+"----否则获得obj1锁");

                    }
                }
            }
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48

jstack分析
把打印信息拉到最后可以发现1个死锁信息。
image.png

2.5、jmap

# 打印出堆内存相关信息
jmap -heap PID
  • 1
  • 2

image.png

# 生成堆快照
jmap -dump:format=b,file=heap.hprof PID
  • 1
  • 2

image.png

一般在开发中,JVM参数可以加上下面两句,这样内存溢出时,会自动dump出该文件

-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=heap.hprof

3、你会估算GC频率吗?

正常情况我们应该根据我们的系统来进行一个内存的估算,这个我们可以在测试环境进行测试,最开始可以将内存设置的大一些,比如4G这样,当然这也可以根据业务系统估算来的。

比如从数据库获取一条数据占用128个字节,需要获取1000条数据,那么一次读取到内存的大小就是((128 B/1024 Kb/1024M)* 1000 = 0.122M,那么我们程序可能需要并发读取,比如每秒读取100次,那么内存占用就是0.122100 = 12.2M,如果堆内存设置1个G,那么年轻代大小大约就是333M,那么333M*80%/12.2M =21.84s,也就是说我们的程序几乎每分钟进行两到三次youngGC。这样可以让我们对系统有一个大致的估算。

4、 内存溢出(OOM)怎么解决?

发生内存溢出一般会有两个原因:

  • 内存不够用:大并发情况下
  • 代码问题:内存泄露导致内存溢出

4.1、大并发[秒杀]

缓存、CDN、集群+负载均衡、限流等方式解决

4.2、内存泄露导致内存溢出

  • jstack查看线程情况,有没有死锁或者IO阻塞的情况,查找可能出现问题的类名或等待时间最长的进程号。

    jstack PID
    
    • 1
  • 查看堆内存的使用,获取到jvm.hprof文件,上传到指定的工具分析,比如heaphero.io

    jmap -heap PID
    
    • 1
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小桥流水78/article/detail/960322
推荐阅读
相关标签
  

闽ICP备14008679号