JVM运行时参数

在这里插入图片描述

1.JVM参数选项

参数来源:
在这里插入图片描述

1.1 :标准参数选项

在这里插入图片描述

1.2 :-X参数选项

在这里插入图片描述在这里插入图片描述-Xmx -Xms -Xss属于XX参数
单位:k/K、m/M、g/G
设置:-Xmx、-Xms最好设置成一样的值,避免扩容带来的损耗
在这里插入图片描述在这里插入图片描述使用-X格式的直接在后面跟数字,使用-XX格式的注意有=号

1.3 -XX参数选项

在这里插入图片描述格式:-XX:
+号表示启用,-号表示不启用
在这里插入图片描述key=value格式的有=
在这里插入图片描述在这里插入图片描述并不是所有的参数都支持动态修改,可以使用命令过滤一下 java -XX:+PrintFlagsFinal -version | grep manageable
在这里插入图片描述

2. 添加JVM参数选项

在这里插入图片描述运行jar包
java -Xms50m -Xmx50m -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -jar demo.jar
程序运行过程中
使用jinfo -flag = 设置非Boolean类型参数
使用jinfo -flag [+|-] 设置Boolean类型参数
并不是所有的参数都支持动态修改,可以修改参数见上文。

3. 常用的JVM参数选项

在这里插入图片描述

3.1 打印设置的XX选项及值

在这里插入图片描述-XX:+PrintFlagsFinal
在这里插入图片描述

3.2 堆、栈、方法区等内存大小设置


在这里插入图片描述

在这里插入图片描述UseAdaptiveSizePolicy参数
在这里插入图片描述
-XX:+UseAdaptiveSizePolicy参数默认开启,会导致-XX:SurvivorRatio=8该参数失效。
在这里插入图片描述如果-XX:SurvivorRatio=8参数显式定义了,-XX:+UseAdaptiveSizePolicy参数开与不开都是8

JDK8默认使用的ParallelGC+ParallelOldGC,MaxTenuringThreshold默认为15。
在这里插入图片描述在这里插入图片描述设置使用CMS收集器,此时会默认启用ParNewGC为新生代收集器。ParNewGC的MaxTenuringThreshold默认为6。
-XX:+UseConcMarkSweepGC
在这里插入图片描述在这里插入图片描述
方法区与直接内存
在这里插入图片描述

3.3 OutOfMemory相关的选项

-XX:+HeapDumpOnOutMemoryError
-XX:+HeapDumpBeforeFullGC
-XX:HeapDumpPath=
-XX:OnOutOfMemoryError
在这里插入图片描述 在这里插入图片描述

3.4 垃圾收集器相关选项

在这里插入图片描述
查看默认的垃圾回收器
在这里插入图片描述
以下两种方式都可以查看默认使用的垃圾回收器,第一种方式更加实用,但是需要程序的支持;第二种方式需要去尝试,如果使用了,返回的值中有+号,否则就是-号
-XX:+PrintCommandLineFlags
在这里插入图片描述在这里插入图片描述
Serial回收器
Seria收集器作为HotSpot中Client模式下的默认新生代垃圾收集器。Serial old是运行在Client模式下默认的老年代的垃圾回收器。
-XX:+UseSerialGC
指定年轻代和老年代都使用串行收集器。等价于新生代用Serial GC,且老年代用Serial Old GC。可以获得最高的单线程收集效率。

Parnew回收器
-XX :+UseParNewGC
手动指定使用ParNew收集器执行内存回收任务。它表示年轻代使用并行收集器,不影响老年代。
-XX:ParallelGCThreads=N
限制线程数量,默认开启和CPU数据相同的线程数。

Parallel回收器
-XX:+UseParallelGC手动指定年轻代使用Parallel并行收集器执行内存回收任务。
-XX:+UseParallelOldGC手动指定老年代都是使用并行回收收集器。
分别适用于新生代和老年代。默认jdk8是开启的。
上面两个参数,默认开启一个,另一个也会被开启。(互相激活)
-XX:ParallelGCThreads 设置年轻代并行收集器的线程数。一般地,最好与CPU数量相等,以避免过多的线程数影响垃圾收集性能。
在默认情况下,当CPU 数量小于8个,ParallelGCThreads 的值等于CPU 数量。
当CPU数量大于8个,ParallelGCThreads的值等于3+[5*CPu_Count]/8]。
-XX:MaxGCPauseMillis设置垃圾收集器最大停顿时间(即STw的时间)。单位是毫秒。
为了尽可能地把停顿时间控制在MaxGCPauseMills以内,收集器在工作时会调整Java堆大小或者其他一些参数。
对于用户来讲,停顿时间越短体验越好。但是在服务器端,我们注重高并发,整体的吞吐量。所以服务器端适合Paralle1,进行控制。该参数使用需谨慎。
-XX:GCTimeRatio垃圾收集时间占总时间的比例(= 1/ (N + 1))。用于衡量吞吐量的大小。取值范围(0,100)。默认值99,也就是垃圾回收时间不超过1%。
与前一个-XX:MaxGCPauseMillis参数有一定矛盾性。暂停时间越长,Radio参数就容易超过设定的比例。
-XX:+UseAdaptivesizePolicy 设置Parallel Scavenge收集器具有自适应调节策略
在这种模式下,年轻代的大小、Eden和Survivor的比例、晋升看年代的对象年龄等参数会被自动调整,已达到在堆大小、吞吐量和停顿时间之间的平衡点。
在手动调优比较困难的场合,可以直接使用这种自适应的方式,仅指定虚拟机的最大堆、目标的吞吐量(GCTimeRatio)和停顿时间(MaxGCPauseNills),让虚拟机自己完成调优工作。

CMS回收器
-XX:+UseConcMarkSweepGC手动指定使用CMS收集器执行内存回收任务。
开启该参数后会自动将-XX:+UseParNewGC打开。即:ParNew(Young区用)+CMS(Old区用)+Serial Old的组合。
-XX:CMSInitiatingOccupanyFraction设置堆内存使用率的阙值,一旦达到该阈值,便开始进行回收。
JDK5及以前版本的默认值为68,即当老年代的空间使用率达到68%时,会执行一次CMS回收。
JDK6及以上版本默认值为92%
如果内存增长缓慢,则可以设置一个稍大的值,大的阈值可以有效降低CNS的触发频率,减少老年代回收的次数可以较为明显地改善应用程序性能。反之,如果应用程序内存使用率增长很快,则应该降低这个阈值,以避免频繁触发老年代串行收集器。因此通过该选项便可以有效降低Full GC的执行次数。
-XX:+UseCMSCompactAtFullCollection用于指定在执行完Full GC后对内存空间进行压缩整理,以此避免内存碎片的产生。不过由于内存压缩整理过程无法并发执行,所带来的问题就是停顿时间变得更长了。默认是开启的。
-XX:CMSFullGCsBeforeCompaction设置在执行多少次Full GC后对内存空间进行压缩整理。默认值为 0,代表每次进入 Full GC 都会触发压缩,带压缩动作的算法为单线程 Serial Old 算法,暂停时间(STW)时间非常长,需要尽可能减少压缩时间。
-XX: ParallelCMSThreads设置CMS的线程数量。
CMS 默认启动的线程数是(ParallelGCThreads+3)/4,ParallelGCThreads是年轻代并行收集器的线程数。当CPU资源比较紧张时,受到CMS收集器线程的影响,应用程序的性能在垃圾回收阶段可能会非常糟糕。
补充参数
另外,CMS收集器还有如下常用参数:
-XX:ConcGCThreads:设置并发垃圾收集的线程数,默认该值是基于ParallelGCThreads计算出来的;
-XX:+UseCMSInitiatingOccupancyOnly:是否动态可调,用这个参数可以使CMS一直按CMSInitiatingoccupancyFraction设定的值启动
-XX:+CMSScavengeBeforeRemark:强制hotspot虚拟机在cms remark阶段之前做一次minor gc,用于提高remark阶段的速度;
-XX:+CMSClassUnloadingEnable:如果有的话,启用回收Perm 区(JDK8之前)
-XX:+CMSParallelInitialEnabled:用于开启CMS initial-mark阶段采用多线程的方式进行标记,用于提高标记速度,在Java8开始已经默认开启;
-XX:+CMSParallelRemarkEnabled:用户开启CMS remark阶段采用多线程的方式进行重新标记,默认开启;
-XX:+ExplicitGCInvokesConcurrent:通过使用System.GC()请求启用并发GC(CMS GC而不是FULL GC)的调用。默认情况下,此选项处于禁用状态,只能与-XX:+UseConcMarkSweepGC选项一起启用。
-XX:+ExplicitGCInvokesConcurrentAndUnloadsClasses:通过使用System.GC()请求和在并发GC循环期间卸载类,启用对并发GC的调用。默认情况下,此选项处于禁用状态,只能与-XX:+UseConcMarkSweepGC选项一起启用。
-XX:+CMSPrecleaningEnabled:指定CMS是否需要进行Pre cleaning这个阶段

特别说明
JDK9新特性:CMS被标记为Deprecate了 (JEP291)
如果对JDK 9及以上版本的HotSpot虚拟机使用参数-XX:
+UseConcMarkSweepGC来开启CMS收集器的话,[用户会收到一个警告信息,提示CMS未来将会被废弃。
JDK14新特性:删除CMS垃圾回收器(JEP363)
移除了CMS垃圾收集器,如果在3DK14中使用-XX:+UseConcMarkSweepGC的话,JVM不会报错,只是给出一个warning信息,但是不会exit。JVM会自动回退,以默认GC方式启动JVM
OpenJDK 64-Bit Server VM warning: Ignoring option useConcMarkSweep6C;support was removed in 14.0 and the VM will continue execution using the default collector.

G1回收器
-XX:+UseG1GC:手动指定使用G1收集器执行内存回收任务。
-XX:G1HeapRegionSize
设置每个Region的大小。值是2的幂,范围是1MB到32MB之间,目标是根据最小的Java堆大小划分出约2048个区域。默认是堆内存的1/2000。
-XX:MaxGCPauseMillis:设置期望达到的最大Gc停顿时间指标(JVM会尽力实现,但不保证达到)。默认值是200ms
-XX: Paralle1GCThread:设置STW时Gc线程数的值。最多设置为8
-XX:ConcGCThreads:设置并发标记的线程数。将n设置为并行垃圾回收线程数(ParallelGCThreads)的1/4左右。
-XX: InitiatingHeapOccupancyPercent
设置触发并发GC周期的Java堆占用率阈值。超过此值,就触发GC。默认值是45。
-XX:G1NewSizePercent、-XX:G1MaxNewSizePercent
新生代占用整个堆内存的最小百分比(默认5%)、最大百分比(默认60%)
-XX:G1ReservePercent=10
保留内存区域,防止 to space ( survivor中的to区)溢出

Mixed GC调优参数
注意:G1收集器主要涉及到Mixed GC,Mixed GC会回收young区和部分old区。
G1关于Mixed GC调优常用参数:
-XX:InitiatingHeap0ccupancyPercent:设置堆占用率的百分比(0到100)达到这个数值的时候触发global concurrent marking(全局并发标记),默认为45%。值为0表示间断进行全局并发标记。
-XX:G1MixedGCLiveThresholdPercent:设置old区的region被回收时候的对象占比,默认占用率为85%。只有old区的region中存活的对象占用达到了这个百分比,才会在Mixed GC中被回收。
-XX:G1HeapWastePercent:在global concurrent marking(全局并发标记)结束之后,可以知道所有的区有多少空间要被回收,在每次young GC之后和再次发生Mixed GC之前,会检查垃圾占比是否达到此参数,只有达到了,下次才会发生Mixed GC。
-XX:G1MixedGCCountTarget:一次global concurrent marking(全局并发标记)之后,最多执行Mixed GC的次数,默认是8。
-XX:G1OldCSetRegionThresholdPercent:设置Mixed GC收集周期中要收集的old region数的上限。默认值是Java堆的10%

怎么选择垃圾回收器
优先调整堆的大小让JVM自适应完成。·如果内存小于100M,使用串行收集器
如果是单核、单机程序,并且没有停顿时间的要求,串行收集器
如果是多CPU、需要高吞吐量、允许停顿时间超过1秒,选择并行或者JVM自己选择
如果是多CPU↓追求低停顿时间,需快速响应(比如延迟不能超过1秒,如互联网应用),使用并发收集器。官方推荐G1,性能高。现在且联网的项日,基本都使用G1。
特别说明:
没有最好的收集器,更没有万能的收集;
调优永远是针对特定场景、特定需求,不存在一劳永逸的收集器

3.5 GC日志相关选项

在这里插入图片描述
-XX:+PrintGCDetails更详细,包含了-XX:+PrintGC或-verbose:gc的内容,所以单独使用PrintGCDetails就可以了。

3.6 其他参数

在这里插入图片描述

4.通过Java代码获取JVM参数

Java提供了java.lang.management包用于监视和管理]ava虚拟机和Java运行时中的其他组件,它允许本地和远程监控和管理运行的Java虚拟机。其中ManagementFactory这个类还是挺常用的。另外还有Runtime类也可以获取一些内存、CPu核数等相关的数据。
通过这些api可以监控我们的应用服务器的堆内存使用情况,设置一些阈值进行报警等处理。

/**
 *
 * 监控我们的应用服务器的堆内存使用情况,设置一些阈值进行报警等处理
 *
 * @author shkstart
 * @create 15:23
 */
public class MemoryMonitor {
    public static void main(String[] args) {
        MemoryMXBean memorymbean = ManagementFactory.getMemoryMXBean();
        MemoryUsage usage = memorymbean.getHeapMemoryUsage();
        System.out.println("INIT HEAP: " + usage.getInit() / 1024 / 1024 + "m");
        System.out.println("MAX HEAP: " + usage.getMax() / 1024 / 1024 + "m");
        System.out.println("USE HEAP: " + usage.getUsed() / 1024 / 1024 + "m");
        System.out.println("\nFull Information:");
        System.out.println("Heap Memory Usage: " + memorymbean.getHeapMemoryUsage());
        System.out.println("Non-Heap Memory Usage: " + memorymbean.getNonHeapMemoryUsage());

        System.out.println("=======================通过java来获取相关系统状态============================ ");
        System.out.println("当前堆内存大小totalMemory " + (int) Runtime.getRuntime().totalMemory() / 1024 / 1024 + "m");// 当前堆内存大小
        System.out.println("空闲堆内存大小freeMemory " + (int) Runtime.getRuntime().freeMemory() / 1024 / 1024 + "m");// 空闲堆内存大小
        System.out.println("最大可用总堆内存maxMemory " + Runtime.getRuntime().maxMemory() / 1024 / 1024 + "m");// 最大可用总堆内存大小

    }
}

上篇通过Runtime获取

/**
 * 1. 设置堆空间大小的参数
 * -Xms 用来设置堆空间(年轻代+老年代)的初始内存大小
 *      -X 是jvm的运行参数
 *      ms 是memory start
 * -Xmx 用来设置堆空间(年轻代+老年代)的最大内存大小
 *
 * 2. 默认堆空间的大小
 *    初始内存大小:物理电脑内存大小 / 64
 *             最大内存大小:物理电脑内存大小 / 4
 * 3. 手动设置:-Xms600m -Xmx600m
 *     开发中建议将初始堆内存和最大的堆内存设置成相同的值。
 *
 * 4. 查看设置的参数:方式一: jps   /  jstat -gc 进程id
 *                  方式二:-XX:+PrintGCDetails
 * @author shkstart  shkstart@126.com
 * @create 2020  20:15
 */
public class HeapSpaceInitial {
    public static void main(String[] args) {

        //返回Java虚拟机中的堆内存总量
        long initialMemory = Runtime.getRuntime().totalMemory() / 1024 / 1024;
        //返回Java虚拟机试图使用的最大堆内存量
        long maxMemory = Runtime.getRuntime().maxMemory() / 1024 / 1024;

        System.out.println("-Xms : " + initialMemory + "M");
        System.out.println("-Xmx : " + maxMemory + "M");

        System.out.println("系统内存大小为:" + initialMemory * 64.0 / 1024 + "G");
        System.out.println("系统内存大小为:" + maxMemory * 4.0 / 1024 + "G");

        try {
            Thread.sleep(1000000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

注:本文是学习 尚硅谷宋红康JVM全套教程(详解java虚拟机)所做笔记。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值