JVM相关参数详解

jvm的运行参数

在jvm中有很多的参数可以进行设置,这样可以让jvm在各种环境中都能够高效的运行。绝大部分的参数保持默认
即可。

三种参数类型

jvm的参数类型分为三类,分别是:

  • 标准参数
    -help
    -version
  • -X参数 (非标准参数)
    -Xint
    -Xcomp
  • -XX参数(使用率较高)
    -XX:newSize
    -XX:+UseSerialGC

标准参数

jvm的标准参数,一般都是很稳定的,在未来的JVM版本中不会改变

#打印帮助信息 java -help 
#查看jvm版本 java -version

在这里插入图片描述

-server与-client参数

可以通过-server或-client设置jvm的运行参数。

  • 它们的区别是Server VM的初始堆空间会大一些,默认使用的是并行垃圾回收器,启动慢运行快。
  • Client VM相对来讲会保守一些,初始堆空间会小一些,使用串行的垃圾回收器,它的目标是为了让JVM的启
    动速度更快,但运行速度会比Server模式慢些。
  • JVM在启动的时候会根据硬件和操作系统自动选择使用Server还是Client类型的JVM。
  • 32位操作系统
    如果是Windows系统,不论硬件配置如何,都默认使用Client类型的JVM。
    如果是其他操作系统上,机器配置有2GB以上的内存同时有2个以上CPU的话默认使用server模式,否则
    使用client模式。
  • 64位操作系统
    只有server类型,不支持client类型。

-X 参数

在这里插入图片描述

-Xint、-Xcomp、-Xmixed

  • 在解释模式(interpreted mode)下,-Xint标记会强制JVM执行所有的字节码,当然这会降低运行速度,通常低
    10倍或更多。
  • -Xcomp参数与它(-Xint)正好相反,JVM在第一次使用时会把所有的字节码编译成本地代码,从而带来最大
    程度的优化。
    然而,很多应用在使用-Xcomp也会有一些性能损失,当然这比使用-Xint损失的少,原因是-xcomp没有
    让JVM启用JIT编译器的全部功能。JIT编译器可以对是否需要编译做判断,如果所有代码都进行编译的
    话,对于一些只执行一次的代码就没有意义了。
  • -Xmixed是混合模式,将解释模式与编译模式进行混合使用,由jvm自己决定,这是jvm默认的模式,也是推
    荐使用的模式。

-XX参数

-XX参数也是非标准参数,主要用于jvm的调优和debug操作。
-XX参数的使用有2种方式,一种是boolean类型,一种是非boolean类型:

  • boolean类型

格式:-XX:[±] 表示启用或禁用属性
如:-XX:+DisableExplicitGC 表示禁用手动调用gc操作,也就是说调用System.gc()无效

  • 非boolean类型

格式:-XX:= 表示属性的值为
如:-XX:NewRatio=4 表示新生代和老年代的比值为1:4

-Xms与-Xmx参数

-Xms与-Xmx分别是设置jvm的堆内存的初始大小和最大大小。
-Xmx2048m:等价于-XX:MaxHeapSize,设置JVM最大堆内存为2048M。
-Xms512m:等价于-XX:InitialHeapSize,设置JVM初始堆内存为512M。
适当的调整jvm的内存大小,可以充分利用服务器资源,让程序跑的更快。

查看正在运行的jvm参数

如果想要查看正在运行的jvm就需要借助于jinfo命令查看。

D:\ccct\code>jps -l
1328 org.jetbrains.idea.maven.server.RemoteMavenServer
3984 sun.tools.jps.Jps
10152 org.jetbrains.jps.cmdline.Launcher
14012

D:\ccct\code>jinfo -flags 10152
Attaching to process ID 10152, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.101-b13
Non-default VM flags: -XX:CICompilerCount=3 -XX:InitialHeapSize=134217728 -XX:MaxHeapSize=734003200 -XX
:MaxNewSize=244318208 -XX:MinHeapDeltaBytes=524288 -XX:NewSize=44564480 -XX:OldSize=89653248 -XX:+UseCo
mpressedClassPointers -XX:+UseCompressedOops -XX:+UseFastUnorderedTimeStamps -XX:-UseLargePagesIndividu
alAllocation -XX:+UseParallelGC
Command line: ....

jstat

jstat命令可以查看堆内存各部分的使用量,以及加载类的数量。命令的格式如下:
jstat [-命令选项] [vmid] [间隔时间/毫秒] [查询次数]

查看class加载统计

D:\ccct\code>jstat -class 10152
Loaded  Bytes  Unloaded  Bytes     Time
  3544  6656.2        0     0.0       1.37

说明:

  • Loaded:加载class的数量
  • Bytes:所占用空间大小
  • Unloaded:未加载数量
  • Bytes:未加载占用空间
  • Time:时间

查看编译统计

D:\ccct\code>jstat -compiler 10152
Compiled Failed Invalid   Time   FailedType FailedMethod
    2131      0       0     2.85          0

说明:

  • Compiled:编译数量。
  • Failed:失败数量
  • Invalid:不可用数量
  • Time:时间
  • FailedType:失败类型
  • FailedMethod:失败的方法

垃圾回收统计

D:\ccct\code>jstat -gc 10152
 S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC
    YGCT    FGC    FGCT     GCT
10240.0 5120.0  0.0   5108.3 66560.0  21050.8   87552.0    10742.4   20352.0 19865.8 2432.0 2269.7
   5    0.035   0      0.000    0.035

说明:

  • S0C:第一个Survivor区的大小(KB)
  • S1C:第二个Survivor区的大小(KB)
  • S0U:第一个Survivor区的使用大小(KB)
  • S1U:第二个Survivor区的使用大小(KB)
  • EC:Eden区的大小(KB)
  • EU:Eden区的使用大小(KB)
  • OC:Old区大小(KB)
  • OU:Old使用大小(KB)
  • MC:方法区大小(KB)
  • MU:方法区使用大小(KB) CCSC:压缩类空间大小(KB) CCSU:压缩类空间使用大小(KB) YGC:年轻代垃圾回收次数
  • YGCT:年轻代垃圾回收消耗时间
  • FGC:老年代垃圾回收次数
  • FGCT:老年代垃圾回收消耗时间
  • GCT:垃圾回收消耗总时间

死锁问题排查

有些时候我们需要查看下jvm中的线程执行情况,比如,发现服务器的CPU的负载突然增高了、出现了死锁、死循
环等,我们该如何分析呢?
由于程序是正常运行的,没有任何的输出,从日志方面也看不出什么问题,所以就需要看下jvm的内部线程的执行
情况,然后再进行分析查找出原因。
这个时候,就需要借助于jstack命令了,jstack的作用是将正在运行的jvm的线程 情况进行快照,并且打印出来:

# jstack <pid>

死锁代码

public class T2_DeadLock {
    private static Object obj1 = new Object();
    private static Object obj2 = new Object();

    public static void main(String[] args){
        new Thread(new Thread1()).start();
        new Thread(new Thread2()).start();
    }

    private static class Thread1 implements Runnable{

        @Override
        public void run() {
            synchronized (obj1){
                System.out.println("Thread1 拿到了obj1的锁!");

                try{
                    //停顿2,保证Thread2线程拿到obj2的锁
                    Thread.sleep(2000);
                }catch (Exception e){
                    e.printStackTrace();
                }
                synchronized (obj2){
                    System.out.println("Thread1 拿到了obj2的锁!");
                }
            }
        }
    }
    private static class Thread2 implements Runnable{

        @Override
        public void run() {
            synchronized (obj2){
                System.out.println("Thread2 拿到了obj2的锁!");

                try{
                    //停顿2,保证Thread2线程拿到obj2的锁
                    Thread.sleep(2000);
                }catch (Exception e){
                    e.printStackTrace();
                }
                synchronized (obj1){
                    System.out.println("Thread2 拿到了obj1的锁!");
                }
            }
        }
    }
}

在这里插入图片描述
分析

# 查询进程号
D:\ccct\code>jps -l
1328 org.jetbrains.idea.maven.server.RemoteMavenServer
9492 sun.tools.jps.Jps
13000 com.gzcctd.itcast.jvm.T2_DeadLock
12220 org.jetbrains.jps.cmdline.Launcher
14012

# 查看现场状态
D:\ccct\code>jstack 13000
2022-03-25 16:07:16
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.101-b13 mixed mode):

"DestroyJavaVM" #13 prio=5 os_prio=0 tid=0x0000000002f72800 nid=0x13b4 waiting on condition [0x000000
0000000000]
   java.lang.Thread.State: RUNNABLE

"Thread-1" #12 prio=5 os_prio=0 tid=0x0000000019aa5000 nid=0x3348 waiting for monitor entry [0x000000
001a5cf000]
   java.lang.Thread.State: BLOCKED (on object monitor)
        at com.gzcctd.itcast.jvm.T2_DeadLock$Thread2.run(T2_DeadLock.java:45)
        - waiting to lock <0x00000000d5b1bee0> (a java.lang.Object)
        - locked <0x00000000d5b1bef0> (a java.lang.Object)
        at java.lang.Thread.run(Thread.java:745)

"Thread-0" #11 prio=5 os_prio=0 tid=0x0000000019a73000 nid=0x2a8c waiting for monitor entry [0x000000
001a4cf000]
   java.lang.Thread.State: BLOCKED (on object monitor)
        at com.gzcctd.itcast.jvm.T2_DeadLock$Thread1.run(T2_DeadLock.java:26)
        - waiting to lock <0x00000000d5b1bef0> (a java.lang.Object)
        - locked <0x00000000d5b1bee0> (a java.lang.Object)
        at java.lang.Thread.run(Thread.java:745)

"Service Thread" #10 daemon prio=9 os_prio=0 tid=0x0000000019a0e800 nid=0x2740 runnable [0x0000000000
000000]
   java.lang.Thread.State: RUNNABLE

"C1 CompilerThread2" #9 daemon prio=9 os_prio=2 tid=0x000000001995e000 nid=0x1d98 waiting on conditio
n [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread1" #8 daemon prio=9 os_prio=2 tid=0x0000000019959800 nid=0x730 waiting on condition
 [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread0" #7 daemon prio=9 os_prio=2 tid=0x0000000019959000 nid=0x20f8 waiting on conditio
n [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Monitor Ctrl-Break" #6 daemon prio=5 os_prio=0 tid=0x000000001995d000 nid=0x25f0 runnable [0x0000000
019ecf000]
   java.lang.Thread.State: RUNNABLE
        at java.net.SocketInputStream.socketRead0(Native Method)
        at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
        at java.net.SocketInputStream.read(SocketInputStream.java:170)
        at java.net.SocketInputStream.read(SocketInputStream.java:141)
        at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
        at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
        at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
        - locked <0x00000000d5bb68f0> (a java.io.InputStreamReader)
        at java.io.InputStreamReader.read(InputStreamReader.java:184)
        at java.io.BufferedReader.fill(BufferedReader.java:161)
        at java.io.BufferedReader.readLine(BufferedReader.java:324)
        - locked <0x00000000d5bb68f0> (a java.io.InputStreamReader)
        at java.io.BufferedReader.readLine(BufferedReader.java:389)
        at com.intellij.rt.execution.application.AppMainV2$1.run(AppMainV2.java:64)

"Attach Listener" #5 daemon prio=5 os_prio=2 tid=0x0000000017e74000 nid=0x33f4 waiting on condition [
0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Signal Dispatcher" #4 daemon prio=9 os_prio=2 tid=0x000000001981b800 nid=0x9d4 runnable [0x000000000
0000000]
   java.lang.Thread.State: RUNNABLE

"Finalizer" #3 daemon prio=8 os_prio=1 tid=0x0000000003069800 nid=0x27a0 in Object.wait() [0x00000000
197ce000]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x00000000d5988ee0> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143)
        - locked <0x00000000d5988ee0> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:164)
        at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:209)

"Reference Handler" #2 daemon prio=10 os_prio=2 tid=0x0000000003065800 nid=0x19ec in Object.wait() [0
x00000000196cf000]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x00000000d5986b50> (a java.lang.ref.Reference$Lock)
        at java.lang.Object.wait(Object.java:502)
        at java.lang.ref.Reference.tryHandlePending(Reference.java:191)
        - locked <0x00000000d5986b50> (a java.lang.ref.Reference$Lock)
        at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)

"VM Thread" os_prio=2 tid=0x0000000017e27800 nid=0x3410 runnable

"GC task thread#0 (ParallelGC)" os_prio=0 tid=0x0000000002f88800 nid=0x3418 runnable

"GC task thread#1 (ParallelGC)" os_prio=0 tid=0x0000000002f8a000 nid=0x31a0 runnable

"GC task thread#2 (ParallelGC)" os_prio=0 tid=0x0000000002f8b800 nid=0x220c runnable

"GC task thread#3 (ParallelGC)" os_prio=0 tid=0x0000000002f8d000 nid=0x2ff0 runnable

"GC task thread#4 (ParallelGC)" os_prio=0 tid=0x0000000002f8f800 nid=0x29ac runnable

"GC task thread#5 (ParallelGC)" os_prio=0 tid=0x0000000002f90800 nid=0x118 runnable

"VM Periodic Task Thread" os_prio=2 tid=0x0000000019a10800 nid=0x3064 waiting on condition

JNI global references: 33


Found one Java-level deadlock:
=============================
"Thread-1":
  waiting to lock monitor 0x0000000017e31728 (object 0x00000000d5b1bee0, a java.lang.Object),
  which is held by "Thread-0"
"Thread-0":
  waiting to lock monitor 0x0000000017e30288 (object 0x00000000d5b1bef0, a java.lang.Object),
  which is held by "Thread-1"

Java stack information for the threads listed above:
===================================================
"Thread-1":
        at com.gzcctd.itcast.jvm.T2_DeadLock$Thread2.run(T2_DeadLock.java:45)
        - waiting to lock <0x00000000d5b1bee0> (a java.lang.Object)
        - locked <0x00000000d5b1bef0> (a java.lang.Object)
        at java.lang.Thread.run(Thread.java:745)
"Thread-0":
        at com.gzcctd.itcast.jvm.T2_DeadLock$Thread1.run(T2_DeadLock.java:26)
        - waiting to lock <0x00000000d5b1bef0> (a java.lang.Object)
        - locked <0x00000000d5b1bee0> (a java.lang.Object)
        at java.lang.Thread.run(Thread.java:745)

Found 1 deadlock.

内存溢出问题排查

查看本专栏中的另一篇文章:文章地址

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java Development Kit (JDK)是Java开发工具包,而JVM参数是为Java虚拟机(JVM)配置的一组参数。JDK8是Java 8版本的JDK,下面我将详细解释JDK8中常用的JVM参数配置。 1. -Xms和-Xmx:这是设置JVM初始化堆内存和最大堆内存的参数。-Xms设定初始堆大小,-Xmx设定最大堆大小。例如,-Xms512m表示初始堆大小为512MB,-Xmx1024m表示最大堆大小为1GB。 2. -Xss:这是设置线程栈大小的参数。默认值根据操作系统和JVM版本而定。可以根据应用程序的需求进行调整。例如,-Xss256k表示线程栈的大小为256KB。 3. -XX:MetaspaceSize和-XX:MaxMetaspaceSize:这是设置元空间(Metaspace)初始大小和最大大小的参数。元空间是Java 8引入的一种取代永久代(PermGen)的存储区域。例如,-XX:MetaspaceSize=128m表示元空间的初始大小为128MB,-XX:MaxMetaspaceSize=256m表示元空间的最大大小为256MB。 4. -XX:NewSize、-XX:MaxNewSize和-XX:SurvivorRatio:这些是控制新生代(Young Generation)内存大小以及Eden区、Survivor区的比例的参数。新生代是堆内存的一部分,存放新创建的对象。可以通过调整这些参数来优化垃圾回收性能。 5. -XX:+UseParallelGC和-XX:+UseConcMarkSweepGC:这些是选择垃圾回收器的参数。Parallel GC(并行垃圾回收器)和CMS(并发标记清除垃圾回收器)是JDK8默认的两种垃圾回收器。分别用于在不同场景下提供更好的垃圾回收性能。 这些只是JDK8中常用的JVM参数配置的一部分。根据实际需求,还有其他许多参数可以进行调整以达到最佳性能和稳定性。重要的是要了解这些参数,并根据应用程序的需求进行适当的配置。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值