本篇文章记录一下日常用到的一些JVM启动参数及相关功能释义

基于Jdk8

  • JVM概述
  • JVM启动配置
  • GC调优

JVM概述

JVM即Java Virtual Machine,用于运行任何被编译为Java bytecode的java程序, 同时兼容各个操作系统底层或硬件差异, 始终保证运行结果一致。可以让java语言做到一处编写, 处处运行的美好体验;

JVM 运行时内存数据区域划分

name

名称

作用

备注

pc Register

pc 寄存器

每个线程独自持有, 标识当前线程所执行代码的位置, 如果执行方法是native, 则无效

Java Virtual Machine Stacks

虚拟机运行栈

在线程创建时产生, 每个线程独自占有, 存储本地变量返回结果

Heap


所有线程共享的运行时数据区, 用来存放所有类实例及数组对象

Method Area

方法区

所有线程共享的方法区, 用来存放编译的代码字节内容, 包含类结构, 常量池, 变量及方法数据

Run-Time Constant Pool

运行时常量区

类或者接口中的常量(即编译期决定不变的数据)存储区域

Native Method Stacks

本地方法栈

调用本地方法时(比如C)存放方法栈的区域

JVM启动配置

JVM加载运行信息输出

可以查看当前所用jdk的一些配置参数默认值

java -XX:+PrintFlagsFinal

JVM 启动时设置此参数, 可以打印加载的所有class信息

-XX:+TraceClassLoading

设置JVM启动运行开启JPDA相关配置参数

设置JVM启动时开启JPDA的debug模式

-agentlib:jdwp=transport=dt_socket,server=y,address=port,suspend=n:

The default value for suspend is y however this can cause the JVM server to lock when the debugging agent attempts to connect. Specifying a suspend value of n should prevent the JVM server from locking.

设置JVM启动时各内存模块大小配置参数

  1. 设置初始堆的大小
-Xms2688M
  1. 设置最大堆的大小
-Xmx2688M

如果在确定服务运行期所需稳定内存大小时,建议设置初始堆和最大堆一样,防止堆抖动;

  1. 设置年轻代 (新生代) 初始和最大堆大小
-Xmn960M

设置了整堆大小和年轻代大小后, 整堆大小减去年轻代大小所剩余的大小就是老年代不超过的大小;

  1. 设置 Java 线程堆栈大小
-Xss32M
  1. 设置初始元数据区大小
    到Java8时, Metaspace(元数据区) 取代 PermGen space(永久代), 用来存放class信息
-XX:MetaspaceSize=512M
  1. 设置最大元数据区大小
-XX:MaxMetaspaceSize=512M
  1. 设置最大堆外内存大小
-XX:MaxDirectMemorySize
  1. 打印GC日志详情, 包含堆上各个代在GC前后的大小信息
-XX:+PrintGCDetails
  1. 打印GC执行的时间戳
-XX:+PrintGCDateStamps
  1. 使显示的调用System.gc()方法进行Full-GC失效;
-XX:+DisableExplicitGC
  1. 打印垃圾回收期间程序暂停的时间;
-XX:+PrintGCApplicationStoppedTime
  1. 打印每次垃圾回收前,程序未中断的执行时间;
-XX:+PrintGCApplicationConcurrentTime

GC调优

GC Collector介绍

  • Serial Garbage Collector- S GC
  • Parallel Garbage Collector- P GC
  • CMS Garbage Collector- CMS GC
  • G1 Garbage Collector- G1 GC
  • Z Garbage Collector- ZGC

各个版本jdk默认使用那个GC(Garbage Collector)

  • Java 7 - P GC
  • Java 8 - P GC
  • Java 9 - G1 GC
  • Java 10- G1 GC
  • Java 11- G1 GC(支持ZGC, 10ms以下的GC停顿)
  • Java 12- G1 GC
  • Java 13- G1 GC
  • Java 14- G1 GC

如何查看默认的GC呢

java -XX:+PrintCommandLineFlags -version ~/Xxx.class

-XX:G1ConcRefinementThreads=8 -XX:GCDrainStackTargetSize=64 -XX:InitialHeapSize=268435456 -XX:MaxHeapSize=4294967296 -XX:MinHeapSize=6815736 -XX:+PrintCommandLineFlags -XX:ReservedCodeCacheSize=251658240 -XX:+SegmentedCodeCache -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseG1GC 
java version "14.0.1" 2020-04-14
Java(TM) SE Runtime Environment (build 14.0.1+7)
Java HotSpot(TM) 64-Bit Server VM (build 14.0.1+7, mixed mode, sharing)

设置采用何种GC垃圾收集器

A. 使用CMSCollector

先给一个我们生产环境中使用CMSCollector的完整JVM参数配置

-Xms4096m -Xmx4096m -XX:NewSize=512m -XX:MaxNewSize=512m -XX:MetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError -Xloggc:/tomcat8/logs/gc.log -XX:HeapDumpPath=/tomcat8/logs/hs_dump_pid%p.hprof -XX:ErrorFile=/tomcat8/logs/hs_err_pid%p.log 
-verbose:gc -XX:+DisableExplicitGC -XX:+UseConcMarkSweepGC -XX:CMSFullGCsBeforeCompaction=1000 -XX:ParallelGCThreads=4 -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCApplicationConcurrentTime -XX:CMSInitiatingOccupancyFraction=75 -XX:+UseCMSInitiatingOccupancyOnly -XX:+ExplicitGCInvokesConcurrentAndUnloadsClasses
  1. Concurrent Mark Sweep (CMS) Collector
    并发标记收集器, 在多个物理处理器的环境中, 应用线程和垃圾收集线程并发执行, 可以满足低延迟的业务需求;
-XX:+UseConcMarkSweepGC
  1. 在使用CMS垃圾收集器时是否启用类卸载,开启的话会对metaSpace/PermGen区间进行扫描清理
-XX:+CMSClassUnloadingEnabled
  1. 在cms gc remark之前做一次ygc,减少gc roots扫描的对象数,从而提高remark的效率
-XX:+CMSScavengeBeforeRemark
  1. 在使用CMS垃圾收集器时指定多少个垃圾并行的收集线程
-XX:ParallelGCThreads=4
  1. 在使用CMS垃圾收集器时由system.gc()触发的gc是否进行类卸载
-XX:+ExplicitGCInvokesConcurrentAndUnloadsClasses
  1. 作为参数CMSInitiatingOccupancyFraction的开关,开启才有用
-XX:+UseCMSInitiatingOccupancyOnly开启
-XX:-UseCMSInitiatingOccupancyOnly关闭
  1. 在开启UseCMSInitiatingOccupancyOnly的情况配置此参数决定老年代使用率达到多少就触发full gc, 默认值是92(92%)
-XX:CMSInitiatingOccupancyFraction=75
  1. 开启在执行CMS-fullGC后对老年代进行空间压缩操作(默认开启)
-XX:+UseCMSCompactAtFullCollection
  1. 指定在执行多少次CMS-fullGC后对老年代进行空间压缩操作(默认是0, 即每次fullGC后都做压缩);
-XX:CMSFullGCsBeforeCompaction=1000
  1. 在调用System.gc()触发fullGC时, 在老年代触发一个并发GC处理, 降低fullGC的延迟时间;
-XX:+ExplicitGCInvokesConcurrent
  1. 在调用System.gc()触发fullGC时, 在元数据区(持久代)触发一个并发GC处理, 降低fullGC的延迟时间;
-XX:+ExplicitGCInvokesConcurrentAndUnloadsClasses

B. 使用G1Collector