JDK 17 之 JVM调优 史诗级 教程

136 篇文章 17 订阅
订阅专栏
131 篇文章 92 订阅
订阅专栏
17 篇文章 1 订阅
订阅专栏

JDK 17 之 JVM调优 史诗级 教程

在这里插入图片描述

文章目录

  • JDK 17 之 JVM调优 史诗级 教程
      • 1 调优层次
      • 2 调优指标
      • 3 JVM调优原则
      • 3.1 优先原则
      • 3.2 堆设置
      • 3.3 年轻代设置
      • 3.4 老年代设置
      • 3.5 方法区设置
      • 3.6 GC设置
      • 3.6.1 GC发展阶段
      • 3.6.2 G1的适用场景
      • 3.6.3 其他收集器适用场景
      • 4 JVM调优步骤
      • 4.1 监控分析
      • 4.1.1 如何生成GC日志
      • 4.1.2 如何产生dump文件
      • 4.1.2.1 JVM的配置文件中配置
      • 4.1.2.2 jmap生成
      • 4.1.2.3 第三方可视化工具生成
      • 4.2 判断
      • 4.3 确定目标
      • 4.4 调整参数
      • 4.5 对比调优前后指标差异
      • 4.6 重复以上过程
      • 4.7 应用
      • 5 JVM调优工具
      • 5.1 jps
      • 5.1.1 使用语法
      • 5.1.2 示例
      • 5.2 jstat
      • 5.2.1 使用语法
      • 5.2.2 options可选值
      • 5.2.3 示例
      • 5.3 jinfo
      • 5.3.1 使用语法
      • 5.3.2 option可选值
      • 5.3.2 示例
      • 5.4 jmap
      • 5.4.1 使用语法
      • 5.4.2 option可选值
      • 5.4.3 示例
      • 5.5 jhat
      • 5.5.1 使用语法
      • 5.5.2 options可选值
      • 5.5.3 示例
      • 5.6 jstack
      • 5.6.1 使用语法
      • 5.6.2 option可选值
      • 5.6.3 示例
      • 5.7 hprof
      • 5.7.1 使用语法
      • 5.7.2 options可选值
      • 5.7.3 示例
      • 5.8 jconsole
      • 5.8.1 如何启动JConsole
      • 5.8.2 如何设置JAVA程序运行时可以被JConsolse连接分析
      • 5.8.3 示例
      • 6 JVM参数
      • 6.1 标准参数
      • 6.2 非标准参数
      • 6.3 不稳定参数
      • 6.4 常参数
      • 6.4.1 -XX:+PrintFlagsInitial、-XX:+PrintFlagsFinal
      • 6.4.2 -XX:+PrintCommandLineFlags
      • 6.4.3 GC日志相关
      • 6.4.4 -XX:CMSFullGCsBeforeCompaction
      • 6.4.5 -XX:HeapDumpPath
      • 6.4.6 -XX:OnOutOfMemoryError
      • 6.4.7 XX:InitialCodeCacheSize
      • 6.4.8 -XX:+UseCodeCacheFlushing
  • 结语

1 调优层次

性能调优包含多个层次,比如:架构调优、代码调优、JVM调优、数据库调优、操作系统调优等。 架构调优和代码调优是JVM调优的基础,其中架构调优是对系统影响最大的。

2 调优指标

  • 吞吐量:运行用户代码的时间占总运行时间的行例 (总运行时间=程序的运行时间+内存回收的时间);
  • 暂停时间:执行垃圾收集时,程序的工作线程被暂停的时间;
  • 内存占用:java堆区所占的内存大小;

这三者共同构成一个“不可能三角”。三者总体的表现会随着技术进步而越来越好。一款优秀的收集器通常最多同时满足其中的两项。

简单来说,主要抓住两点:

  • 吞吐量 吞吐量优先,意味着在单位时间内,STW的时间最短
  • 暂停时间 暂停时间优先,意味这尽可能让单次STW的时间最短

在设计(或使用)GC算法时,必须确定我们的目标:一个GC算法只可能针对两个目标之一(即只专注于较大吞吐量或最小暂停时间),或尝试找一个二者的折衷。

在这里插入图片描述

现在标准,在最大吞吐量优先的情况下,降低停顿时间

3 JVM调优原则

3.1 优先原则

优先架构调优和代码调优,JVM优化是不得已的手段,大多数的Java应用不需要进行JVM优化

3.2 堆设置

参数-Xms和-Xmx,通常设置为相同的值,避免运行时要不断扩展JVM内存,建议扩大至3-4倍FullGC后的老年代空间占用。

3.3 年轻代设置

参数-Xmn,1-1.5倍FullGC之后的老年代空间占用。

避免新生代设置过小,当新生代设置过小时,会带来两个问题:一是minor GC次数频繁,二是可能导致 minor GC对象直接进老年代。当老年代内存不足时,会触发Full GC。 避免新生代设置过大,当新生代设置过大时,会带来两个问题:一是老年代变小,可能导致Full GC频繁执行;二是 minor GC 执行回收的时间大幅度增加。

3.4 老年代设置

  • 注重低延迟的应用

    • 老年代使用并发收集器,所以其大小需要小心设置,一般要考虑并发会话率和会话持续时间等一些参数
    • 如果堆设置偏小,可能会造成内存碎片、高回收频率以及应用暂停
    • 如果堆设置偏大,则需要较长的收集时间
  • 吞吐量优先的应用 一般吞吐量优先的应用都有一个较大的年轻代和一个较小的老年代。原因是,这样可以尽可能回收掉大部分短期对象,减少中期的对象,而老年代尽可能存放长期存活对象

3.5 方法区设置

基于jdk1.7版本,永久代:参数-XX:PermSize和-XX:MaxPermSize; 基于jdk1.8版本,元空间:参数 -XX:MetaspaceSize和-XX:MaxMetaspaceSize; 通常设置为相同的值,避免运行时要不断扩展,建议扩大至1.2-1.5倍FullGc后的永久带空间占用。

3.6 GC设置

3.6.1 GC发展阶段

SerialParallel(并行) CMS(并发) G1ZGC 截至jdk1.8 ,一共有7款不同垃圾收集器。每一款不同的垃圾收集器都有不同的特点,在具体使用的时候,需要根据具体的情况选择不同的垃圾回收器

img

3.6.2 G1的适用场景

  • 面向服务端应用,针对具有大内存、多处理器的机器。(在普通大小的堆里表现并不惊喜)

  • 最主要的应用是需要低GC延迟并具有大堆的应用程序提供解决方案(G1通过每次只清理一部分而不是全部Region的增量式清理来保证每次GC停顿时间不会过长)

  • 在堆大小约6GB或更大时,可预测的暂停时间可以低于0.5秒

  • 用来替换掉JDK1.5中的CMS收集器,以下情况,使用G1可能比CMS好

    • 超过50% 的java堆被活动数据占用
    • 对象分配频率或年代提升频率变化很大
    • GC停顿时间过长(大于0.5至1秒)
  • 从经验上来说,整体而言:

    • 小内存应用上,CMS大概率会优于 G1;
    • 大内存应用上,G1则很可能更胜一筹。 这个临界点大概是在 6~8G 之间(经验值)

3.6.3 其他收集器适用场景

  • 如果你想要最小化地使用内存和并行开销,请选择Serial Old(老年代) + Serial(年轻代)
  • 如果你想要最大化应用程序的吞吐量,请选择Parallel Old(老年代) + Parallel(年轻代)
  • 如果你想要最小化GC的中断或停顿时间,请选择CMS(老年代) + ParNew(年轻代)

4 JVM调优步骤

4.1 监控分析

分析GC日志及dump文件,判断是否需要优化,确定瓶颈问题点。

4.1.1 如何生成GC日志

常用参数部分会详细讲解如何生成GC日志

4.1.2 如何产生dump文件

4.1.2.1 JVM的配置文件中配置

JVM启动时增加两个参数:

# 出现OOME时生成堆dump:
-XX:+HeapDumpOnOutOfMemoryError
# 生成堆文件地址:
-XX:HeapDumpPath=/home/hadoop/dump/

4.1.2.2 jmap生成

发现程序异常前通过执行指令,直接生成当前JVM的dump文件

jmap -dump:file=文件名.dump [pid]
# 9257是指JVM的进程号
jmap -dump:format=b,file=testmap.dump 9257

第一种方式是一种事后方式,需要等待当前JVM出现问题后才能生成dump文件,实时性不高; 第二种方式在执行时,JVM是暂停服务的,所以对线上的运行会产生影响。

所以建议第一种方式。

4.1.2.3 第三方可视化工具生成

4.2 判断

如果各项参数设置合理,系统没有超时日志或异常信息出现,GC频率不高,GC耗时不高,那么没有必要进行GC优化,如果GC时间超过1-3秒,或者频繁GC,则必须优化。 遇到以下情况,就需要考虑进行JVM调优:

  • 系统吞吐量与响应性能不高或下降;
  • Heap内存(老年代)持续上涨达到设置的最大内存值;
  • Full GC 次数频繁;
  • GC 停顿时间过长(超过1秒);
  • 应用出现OutOfMemory等内存异常;
  • 应用中有使用本地缓存且占用大量内存空间;

4.3 确定目标

调优的最终目的都是为了应用程序使用最小的硬件消耗来承载更大的吞吐量或者低延迟。 jvm调优主要是针对垃圾收集器的收集性能优化,减少GC的频率和Full GC的次数,令运行在虚拟机上的应用能够使用更少的内存、高吞吐量、低延迟。

下面列举一些JVM调优的量化目标参考实例,注意:不同应用的JVM调优量化目标是不一样的。

  • 堆内存使用率<=70%;
  • 老年代内存使用率<=70%;
  • avgpause<=1秒;
  • Full GC次数0或avg pause interval>=24小时 ;

4.4 调整参数

调优一般是从满足程序的内存使用需求开始的,之后是时间延迟的要求,最后才是吞吐量的要求。 要基于这个步骤来不断优化,每一个步骤都是进行下一步的基础,不可逆行之。

4.5 对比调优前后指标差异

4.6 重复以上过程

4.7 应用

找到合适的参数,先在单台服务器上试运行,然后将这些参数应用到所有服务器,并进行后续跟踪。

5 JVM调优工具

5.1 jps

jps:JVM Process Status Tool jps可以查看Java进程,相当于Linux下的ps命令,只不过它只列出Java进程。

5.1.1 使用语法

jps:列出Java程序进程ID和Main函数名称
jps -q:只输出进程ID
jps -m:输出传递给Java进程(主函数)的参数
jps -l:输出主函数的完整路径
jps -v:显示传递给Java虚拟的参数

5.1.2 示例

img

02.png

5.2 jstat

jstat:JVM Statistics Monitoring Tool jstat可以查看Java程序运行时相关信息,可以通过它查看堆信息的相关情况

5.2.1 使用语法

jstat -<options> [-t] [-h<lines>] <vmid> [<interval> [<count>]]

5.2.2 options可选值

-class:显示ClassLoader的相关信息
-compiler:显示JIT编译的相关信息
-gc:显示与GC相关信息
-gccapacity:显示各个代的容量和使用情况
-gccause:显示垃圾收集相关信息(同-gcutil),同时显示最后一次或当前正在发生的垃圾收集的诱发原因
-gcnew:显示新生代信息
-gcnewcapacity:显示新生代大小和使用情况
-gcold:显示老年代信息
-gcoldcapacity:显示老年代大小
-gcpermcapacity:显示永久代大小
-gcutil:显示垃圾收集信息
-printcompilation:输出JIT编译的方法信息
-t:在输出信息前加上一个Timestamp列,显示程序的运行时间
-h:可以在周期性数据输出后,输出多少行数据后,跟着一个表头信息
interval:用于指定输出统计数据的周期,单位为毫秒
count:用于指定一个输出多少次数据

5.2.3 示例

示例一 显示GC相关信息

jstat -gc 7063 500 4
7063 是进程ID ,采样时间间隔为500ms,采样数为4

img

03.png

S0C:年轻代中第一个survivor(幸存区)的容量 (字节)
S1C:年轻代中第二个survivor(幸存区)的容量 (字节)
S0U:年轻代中第一个survivor(幸存区)目前已使用空间 (字节)
S1U:年轻代中第二个survivor(幸存区)目前已使用空间 (字节)
EC :年轻代中Eden(伊甸园)的容量 (字节)
EU :年轻代中Eden(伊甸园)前已使空间 (字节)
OC :Old代的容量 (字节)
OU :Old代目前已使用空间 (字节)
MC:metaspace(元空间)的容量 (字节)
MU:metaspace(元空间)目前已使用空间 (字节)
CCSC:压缩类空间大小
CCSU:压缩类空间使用大小
YGC :从应用程序启动到采样时年轻代中gc次数
YGCT :从应用程序启动到采样时年轻代中gc所用时间(s)
FGC :从应用程序启动到采样时old代(全gc)gc次数
FGCT :从应用程序启动到采样时old代(全gc)gc所用时间(s)
GCT:从应用程序启动到采样时gc用的总时间(s)

示例二 显示垃圾收集相关信息

jstat -gcutil 7737 5s 5

img

04.png

S0 年轻代中第一个survivor(幸存区)已使用的占当前容量百分比S1 年轻代中第二个survivor(幸存区)已使用的占当前容量百分比E 年轻代中Eden(伊甸园)已使用的占当前容量百分比O old代已使用的占当前容量百分比M metaspace已使用的占当前容量百分比CCS 压缩使用比例YGC 从应用程序启动到采样时年轻代中gc次数YGCT 从应用程序启动到采样时年轻代中gc所用时间(s)FGC 从应用程序启动到采样时old代(全gc)gc次数FGCT 从应用程序启动到采样时old代(全gc)gc所用时间(s)GCT 从应用程序启动到采样时gc用的总时间(s)

5.3 jinfo

jinfo:Java Configuration Info jinfo可以用来查看正在运行的java程序的扩展参数,甚至支持运行时修改部分参数

5.3.1 使用语法

jinfo [option] <pid>

5.3.2 option可选值

-flag <name> to print the value of the named VM flag-flag [+|-]<name> to enable or disable the named VM flag-flag <name>=<value> to set the named VM flag to the given value-flags to print VM flags-sysprops to print Java system properties<no option> to print both of the above-h | -help to print this help message

5.3.2 示例

示例一

查看堆的最大值

~ jinfo -flag MaxHeapSize 8384
-XX:MaxHeapSize=10485760

示例二

查看所有参数

~ jinfo -flags 8384
Attaching to process ID 8384, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.121-b13
Non-default VM flags: -XX:CICompilerCount=4 -XX:InitialHeapSize=10485760 -
XX:MaxHeapSize=10485760 -XX:MaxNewSize=3145728 -XX:MinHeapDeltaBytes=524288 -
XX:NewSize=3145728 -XX:OldSize=7340032 -XX:+UseCompressedClassPointers -
XX:+UseCompressedOops -XX:+UseFastUnorderedTimeStamps -XX:+UseParallelGC
Command line: -Xms10m -Xmx10m -Dfile.encoding=UTF-8

示例三

查看使用的垃圾回收器

~ jinfo -flag UseParallelGC 8384
-XX:+UseParallelGC
~ jinfo -flag UseConcMarkSweepGC 8384
-XX:-UseConcMarkSweepGC

示例四

设置日志打印

~ jinfo -flag PrintGCDetails 8384-XX:-PrintGCDetails~ jinfo -flag +PrintGCDetails 8384~ jinfo -flag PrintGCDetails 8384-XX:+PrintGCDetails~ jinfo -flag -PrintGCDetails 8384~ jinfo -flag PrintGCDetails 8384-XX:-PrintGCDetails

5.4 jmap

jmap:Memory Map jmap可以查看堆内存使用状况,一般结合jhat使用。

5.4.1 使用语法

 jmap [option] <pid>        (to connect to running process) jmap [option] <executable <core>        (to connect to a core file) jmap [option] [server_id@]<remote server IP or hostname>        (to connect to remote debug server)

option:选项参数。 pid:需要打印配置信息的进程ID。 executable:产生核心dump的Java可执行文件。 core:需要打印配置信息的核心文件。 server-id:可选的唯一id,如果相同的远程主机上运行了多台调试服务器,用此选项参数标识服务器。 remote server IP or hostname:远程调试服务器的IP地址或主机名。

5.4.2 option可选值

<none> to print same info as Solaris pmap-heap to print java heap summary-histo[:live] to print histogram of java object heap; if the "live" suboption is specified, only count live objects-clstats to print class loader statistics-finalizerinfo to print information on objects awaiting finalization-dump:<dump-options> to dump java heap in hprof binary format-F force. Use with -dump:<dump-options> <pid> or -histo to force a heap dump or histogram when <pid> does not respond. The "live" suboption is not supported in this mode.-h | -help to print this help message-J<flag> to pass <flag> directly to the runtime system

no option: 查看进程的内存映像信息,类似 Solaris pmap 命令。 heap: 显示Java堆详细信息 histo[:live]: 显示堆中对象的统计信息 clstats:打印类加载器信息 finalizerinfo: 显示在F-Queue队列等待Finalizer线程执行finalizer方法的对象 dump::生成堆转储快照 F:当-dump没有响应时,使用-dump或者-histo参数。在这个模式下,live子参数无效 help:打印帮助信息 J:指定传递给运行jmap的JVM的参数

dump-options可选值

-live dump only live objects; if not specified,all objects in the heap are dumped.-format=b binary format-file=<file> dump heap to <file>Example:jmap -dump:live,format=b,file=heap.bin <pid>

5.4.3 示例

示例一

显示Java堆详细信息

jmap -heap pid

打印一个堆的摘要信息,包括使用的GC算法、堆配置信息和各内存区域内存使用信息

~ jmap -heap 8985
Attaching to process ID 8985, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.121-b13

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

Heap Configuration:
MinHeapFreeRatio = 0
MaxHeapFreeRatio = 100
MaxHeapSize = 524288000 (500.0MB)
NewSize = 174587904 (166.5MB)
MaxNewSize = 174587904 (166.5MB)
OldSize = 349700096 (333.5MB)
NewRatio = 2
SurvivorRatio = 8
MetaspaceSize = 21807104 (20.796875MB)
CompressedClassSpaceSize = 1073741824 (1024.0MB)
MaxMetaspaceSize = 17592186044415 MB
G1HeapRegionSize = 0 (0.0MB)

Heap Usage:
PS Young Generation
Eden Space:
capacity = 131596288 (125.5MB)
used = 127090976 (121.20339965820312MB)
free = 4505312 (4.296600341796875MB)
96.57641407028137% used
From Space:
capacity = 21495808 (20.5MB)
used = 21477712 (20.482742309570312MB)
free = 18096 (0.0172576904296875MB)
99.91581614424543% used
To Space:
capacity = 21495808 (20.5MB)
used = 0 (0.0MB)
free = 21495808 (20.5MB)
0.0% used
PS Old Generation
capacity = 349700096 (333.5MB)
used = 100703528 (96.03836822509766MB)
free = 248996568 (237.46163177490234MB)
28.79711191157351% used

2156 interned Strings occupying 152440 bytes.

示例二

显示堆中对象的统计信息

jmap -histo:live pid

其中包括每个Java类、对象数量、内存大小(单位:字节)、完全限定的类名。打印的虚拟机内部的类名称将会带有一个’*’前缀。如果指定了live子选项,则只计算活动的对象。

~ jmap -histo:live 8985 num #instances #bytes class name---------------------------------------------- 1: 3682 339156840 [B 2: 3806 408160 [C 3: 3794 91056 java.lang.String 4: 593 67480 java.lang.Class 5: 587 54568 [Ljava.lang.Object; 6: 3273 52368 com.kkb.example.HeapInstanceTest

示例三

打印类加载器信息

jmap -clstats pid

-clstats是-permstat的替代方案,在JDK8之前,-permstat用来打印类加载器的数据打印Java堆内存的永久保存区域的类加载器的智能统计信息。对于每个类加载器而言,它的名称、活跃 度、地址、父类加载器、它所加载的类的数量和大小都会被打印。此外,包含的字符串数量和大小也会被打印。

~ jmap -clstats 8985
Attaching to process ID 8985, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.121-b13
finding class loader instances ..done.
computing per loader stat ..done.
please wait.. computing
liveness......................................................................
.............................done.
class_loader classes bytes parent_loader alive? type
<bootstrap> 517 969116 null live <internal>
0x00000007af095a08 0 0 0x00000007ae86f288 live 
java/util/ResourceBundle$RBClassLoader@0x00000007c00555e8
0x00000007ae86f288 9 29861 0x00000007ae8770f8 live 
sun/misc/Launcher$AppClassLoader@0x00000007c000f6a0
0x00000007ae8770f8 0 0 null live 
sun/misc/Launcher$ExtClassLoader@0x00000007c000fa48
total = 4 526 998977 N/A alive=4, dead=0 N/A

示例四

打印正等候回收的对象的信息

jmap -finalizerinfo pid
~ jmap -finalizerinfo 10067
Attaching to process ID 10067, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.121-b13
Number of objects pending for finalization: 0

Number of objects pending for finalization: 0 说明当前F-QUEUE队列中并没有等待Fializer线程执行final

示例五

生成堆转储快照dump文件

jmap -dump:format=b,file=heapdump.dump pid

以hprof二进制格式转储Java堆到指定filename的文件中。live子选项是可选的。如果指定了live 子选项,堆中只有活动的对象会被转储。想要浏览heap dump,你可以使用jhat(Java堆分析具)读取生成的文件。

这个命令执行,JVM会将整个heap的信息dump写入到个文件,heap如果比较大的话,就会导致这个过程比较耗时,并且执行的过程中为了保证dump的信息是可靠的,所以会暂停应用, 线上系统慎用。

~ jmap -dump:format=b,file=heapdump.dump 10067 Dumping heap to /Users/hadoop/heapdump.dump ...

5.5 jhat

jhat:Java Heap Analysis Tool

jhat 命令解析Java堆转储文件并启动一个 web server,然后用浏览器来查看、浏览 dump 出来的 heap。

jhat 命令支持预先设计的查询,比如显示某个类的所有实例。 还支持对象查询语言(OQL, Object Query Language)。 OQL有点类似SQL,专门用来查询堆转储。

5.5.1 使用语法

jhat [ options ] heap-dump-file

5.5.2 options可选值

-stack false|true关闭对象分配调用栈跟踪(tracking object allocation call stack)。 如果分配位置信息在堆转储中不可用,则必须将此标志设置为 false。 默认值为 true 。-refs false|true关闭对象引用跟踪(tracking of references to objects)。 默认值为 true 。 默认情况下, 返回的指针是指向其他特定对象的对象,如反向链接或输入引用(referrers or incoming references), 会统计、计算堆中的所有对象。-port port-number设置 jhat HTTP server 的端口号。 默认值 7000 。-exclude exclude-file指定对象查询时需要排除的数据成员列表文件(a file that lists data members that should be excluded from the reachable objects query)。 例如, 如果文件列列出了 java.lang.String.value , 那么当从某个特定对象 Object o 计算可达的对象列表时, 引用路径涉及 java.lang.String.value 的都会被排除。-baseline exclude-file指定一个基准堆转储(baseline heap dump)。 在两个 heap dumps 中有相同 object ID 的对象会被标记为不是新的(marked as not being new),其他对象被标记为新的(new)。 在比较两个不同的堆转储时很有用。-debug int设置 debug 级别。 0表示不输出调试信息。 值越大则表示输出更详细的 debug 信息。-version启动后只显示版本信息就退出-h显示帮助信息并退出。 同 -help-help显示帮助信息并退出。 同 -h-J< flag >因为jhat命令实际上会启动一个JVM来执行, 通过 -J 可以在启动JVM时传入一些启动参数。 例如, -J-Xmx512m 则指定运行jhat的Java虚拟机使用的最大堆内存为 512 MB。 如果需要使用多个JVM启动参数,则传多多个 -Jxxxxxx。

5.5.3 示例

利用jhat分析刚刚jmap输出的堆文件

img

05.png

这样就启动起来了一个简易的HTTP服务,端口号是7000,尝试一下用浏览器访问下它,本地的可以通过http://localhost:7000就可以得到这样的页面:

jhat启动后显示的html页面中包含有:

  • All classes including platform:显示出堆中所包含的所有的类
  • Show all members of the rootset :从根集能引用到的对象
  • Show instance counts for all classes (including platform/excluding platform):显示平台包括的所有类的实例数量
  • Show heap histogram:堆实例的分布表
  • Show finalizer summary:Finalizer 摘要
  • Execute Object Query Language (OQL) query:执行对象查询语句(OQL)
select a from [I a where a.length > 256 //查询长度大于256的数组

5.6 jstack

jstack:Java Stack Trace

jstack是java虚拟机自带的一种堆栈跟踪工具。jstack用于生成java虚拟机当前时刻的线程快照。线程快照是当前java虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的是定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待等。 线程出现停顿的时候通过jstack来查看各个线程的调用堆栈,就可以知道没有响应的线程到底在后台做什么事情,或者等待什么资源。

如果java程序崩溃生成core文件,jstack工具可以用来获得core文件的java stack和native stack的信息,从而可以轻松地知道java程序是如何崩溃和在程序何处发生问题。另外,jstack工具还可以附属到正在运行的java程序中,看到当时运行的java程序的java stack和native stack的信息, 如果现在运行的java程序呈现hung的状态,jstack是非常有用的。

5.6.1 使用语法

jstack [ option ] pid 查看当前时间点,指定进程的dump堆栈信息。jstack [ option ] pid > 文件 将当前时间点的指定进程的dump堆栈信息,写入到指定文件中。注:若该文件不存在,则会自动生成;若该文件存在,则会覆盖源文件。jstack [ option ] executable core 查看当前时间点,core文件的dump堆栈信息。jstack [ option ] [server_id@]<remote server IP or hostname> 查看当前时间点,远程机器的dump堆栈信息。

5.6.2 option可选值

-F 强制jstack。当进程挂起了,此时'jstack [-l] pid'是没有响应的,这时候可使用此参数来强制打印堆栈信息,一般情况不需要使用。-m 打印java和native c/c++框架的所有栈信息。可以打印JVM的堆栈,以及Native的栈帧,一般应用排查不需要使用。-l 长列表。打印关于锁的附加信息。例如属于java.util.concurrent的ownable synchronizers列表,会使得JVM停顿得久得多(可能会差很多倍,如普通的jstack可能毫秒和次GC没区别,加了-l 就是近一秒的时间),-l 建议不要用。一般情况不需要使用。-h or -hel 打印帮助信息

在thread dump中,要留意下面几种状态

  • 死锁,Deadlock(重点关注)
  • 等待资源,Waiting on condition(重点关注)
  • 等待获取监视器,Waiting on monitor entry(重点关注)
  • 阻塞,Blocked(重点关注)
  • 执行中,Runnable
  • 暂停,Suspended
  • 对象等待中,Object.wait() 或 TIMED_WAITING
  • 停止,Parked

5.6.3 示例

示例一

img

06.png

示例二 将指定进程的当前堆栈情况记录到某个件中

img

07.png

示例三 统计线程数

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gibiH2fE-1660299442837)(https://pics6.baidu.com/feed/203fb80e7bec54e7c75e1edde61b64584ec26a6b.png?token=157827beeb1a3cb378be8639c8d21cae)]

08.png

示例四 检测死锁

img

09.png

img

10.png

5.7 hprof

hprof:Heap/CPU Profiling Tool 能够展现CPU使用率,统计堆内存使用情况。

J2SE中提供了一个简单的命令行工具来对java程序的cpu和heap进行profiling,叫做HPROF。HPROF实际上是JVM中的一个native的库,它会在JVM启动的时候通过命令行参数来动态加载,并成为JVM进程的一部分。若要在java进程启动的时候使用HPROF,用户可以通过各种命令行参数类型来使用HPROF对java进程的heap或者(和)cpu进行profiling的功能。HPROF产生的profiling数据可以是二进制的,也可以是文本格式的。这些日志可以用来跟踪和分析java进程的性能问题和瓶颈,解决内存使用上不优的地方或者程序实现上的不优之处。二进制格式的日志还可以被JVM中的HAT工具来进行浏览和分析,用以观察java进程的heap中各种类型和数据的情况。在J2SE 5.0以后的版本中,HPROF已经被并入到一个叫做Java Virtual Machine Tool Interface(JVM TI)中。

5.7.1 使用语法

java -agentlib:hprof[=options] ToBeProfiledClassjava -Xrunprof[:options] ToBeProfiledClassjavac -J-agentlib:hprof[=options] ToBeProfiledClass

5.7.2 options可选值

Option Name and Value   Description                     Default---------------------   -----------                     -------heap=dump|sites|all     heap profiling                  allcpu=samples|times|old   CPU usage                       offmonitor=y|n             monitor contention              nformat=a|b              text(txt) or binary output      afile=<file>             write data to file              java.hprof[.txt]net=<host>:<port>       send data over a socket         offdepth=<size>            stack trace depth               4interval=<ms>           sample interval in ms           10cutoff=<value>          output cutoff point             0.0001lineno=y|n              line number in traces?          ythread=y|n              thread in traces?               ndoe=y|n                 dump on exit?                   ymsa=y|n                 Solaris micro state accounting  nforce=y|n               force output to <file>          yverbose=y|n             print messages about dumps      y

img

11.png

5.7.3 示例

官方示例

CPU Usage Sampling Profiling(cpu=samples)的例子 下面每隔20毫秒采样CPU消耗信息,堆栈深度为3,生成的profile文件名称是java.hprof.txt,在当前目录。

java -agentlib:hprof=cpu=samples,interval=20,depth=3 Hello

CPU Usage Times Profiling(cpu=times)的例子 它相对于CPU Usage Sampling Profile能够获得更加细粒度的CPU消耗信息,能够细到每个法调的开始和结束,它的实现使用了字节码注入技术(BCI)

javac -J-agentlib:hprof=cpu=times Hello.java

Heap Allocation Profiling(heap=sites)的例子

javac -J-agentlib:hprof=heap=sites Hello.java

Heap Dump(heap=dump)的例子 它能比上面的Heap Allocation Profiling生成更详细的Heap Dump信息:

javac -J-agentlib:hprof=heap=dump Hello.java

虽然在JVM启动参数中加入-Xrunprof:heap=sites参数可以生成CPU/Heap Profile文件,但对JVM性 能影响非常大,不建议在线上服务器环境使用。

示例一

统计方法耗时

classes java -agentlib:hprof=cpu=times,interval=10 com.kkb.example.HprofTestDumping CPU usage by timing methods ... done.
classes vim java.hprof.txt

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PRHQa1ZI-1660299442839)(https://pics0.baidu.com/feed/d52a2834349b033b01845d3e7dedc9dbd439bdf6.png?token=6a4bf5d39d2964bae903bb3ac3ec50c2)]

12.png

示例二

生成跟踪点类所占内存百分比

classes java -agentlib:hprof=heap=sites com.kkb.example.HprofTestDumping allocation sites ... done.
classes vim java.hprof.txt

img

13.png

5.8 jconsole

Jconsole:Java Monitoring and Management Console,Java 5引入,一个内置 Java 性能分析器,可以从命令行或在 GUI shell 中运行。您可以轻松地使用 JConsole来监控 Java 应用程序性能和跟踪Java 中的代码。

5.8.1 如何启动JConsole

如果是从命令行启动,使 JDK 在 PATH 上,运行 jconsole 即可。 如果从 GUI shell 启动,找到 JDK 安装路径,打开 bin 文件夹,双击 jconsole 。

当分析工具弹出时(取决于正在运行的 Java 版本以及正在运行的 Java 程序数量),可能会出现一个对话框,要求输入一个进程的 URL 来连接,也可能列出许多不同的本地 Java 进程(有时包含JConsole 进程本身)来连接。 如下图所示:想分析哪个程序就双击哪个进程。

img

14.png

5.8.2 如何设置JAVA程序运行时可以被JConsolse连接分析

本地程序(相对于开启JConsole的计算机),无需设置任何参数就可以被本地开启的JConsole连接(Java SE 6开始无需设置,之前还是需要设置运行时参数 -Dcom.sun.management.jmxremote )

JConsole如何连接远程机器的JAVA程序?

jconsole 192.168.0.1:8999

也可以在已经打开的JConsole界面操作,连接新建连接选择远程进程输入远程主机IP和端口号点击“连接”,如下图

img

15.png

5.8.3 示例

示例一 进入视图后包括这六个标签:

  • Overview: 显示有关JVM和监视值的概述信息

  • Memory: 显示内存使用信息

  • Threads: 显示线程使用信息

  • Classes: 显示类装载信息

  • VM Summary:显示java VM信息

  • MBeans: 显示 MBeans

img

16.png

上图描述有我们需要的信息,同时点击右键可以保存数据到CSV文件。

内存页签相对于可视化的jstat 命令,用于监视受收集器管理的虚拟机内存。

img

17.png

6 JVM参数

在这里插入图片描述

在JVM调整过程中,主要是对JVM参数做的调整,以下我们介绍主要参数。JVM参数有很多,其实我们直接使用默认的JVM参数,不去修改都可以满足大多数情况。但是如果你想在有限的硬件资源下,部署的系统达到最大的运行效率,那么进行相关的JVM参数设置是必不可少的。

JVM参数主要分为以下三种:标准参数、非标准参数、不稳定参数。

6.1 标准参数

标准参数,顾名思义,标准参数中包括功能以及输出的结果都是很稳定的,基本上不会随着JVM版本的变化而变化。

标准参数以-开头,如:java -version、java -jar等,通过java -help可以查询所有的标准参数,-help 也是个标准参数。

6.2 非标准参数

非标准参数以-X开头,是标准参数的扩展。对应前面讲的标准化参数,这是非标准化参数。表示在将来的JVM版本中可能会发生改变,但是这类以-X开始的参数变化的比较小。 我们可以通过 Java -X 命令来检索所有-X 参数。

我们可以通过设置非标准参数来配置堆的内存分配,常用的非标准参数有:

  • -Xmn新生代内存的大小,包括Eden区和两个Survivor区的总和,写法如:-Xmn1024,-Xmn1024k,-Xmn1024m,-Xmn1g 。
  • -Xms堆内存的最小值,默认值是总内存/64(且小于1G)。默认情况下,当堆中可用内存小于40%(这个值可以用-XX: MinHeapFreeRatio 调整,如-X:MinHeapFreeRatio=30)时,堆内存会开始增加,直增加到-Xmx的大小。
  • -Xmx堆内存的最大值,默认值是总内存/4(且小于1G)。默认情况下,当堆中可用内存大于70%(这个值可以用-XX: MaxHeapFreeRatio调整,如-X:MaxHeapFreeRatio =80)时,堆内存会开始减少,一直减小到-Xms的大小。 *如果Xms和Xmx都不设置,则两者大小会相同*
  • -Xss每个线程的栈内存,默认1M,般来说是不需要改的。
  • -Xrs减少JVM对操作系统信号的使用。
  • -Xprof跟踪正运行的程序,并将跟踪数据在标准输出输出。适合于开发环境调试。
  • -Xnoclassgc关闭针对class的gc功能。因为其阻至内存回收,所以可能会导致OutOfMemoryError错误,慎用。
  • -Xincgc开启增量gc(默认为关闭)。这有助于减少长时间GC时应用程序出现的停顿,但由于可能和应用程序并发执行,所以会降低CPU对应用的处理能力。
  • -Xloggc:file与-verbose:gc功能类似,只是将每次GC事件的相关情况记录到一个文件中,文件的位置最好在本地,以避免网络的潜在问题。

6.3 不稳定参数

这是我们日常开发中接触到最多的参数类型。这也是非标准化参数,相对来说不稳定,随着JVM版本的变化可能会发生变化,主要用于JVM调优和debug。

不稳定参数以-XX 开头,此类参数的设置很容易引起JVM 性能上的差异,使JVM存在极大的不稳定性。如果此类参数设置合理将大大提高JVM的性能及稳定性。

不稳定参数分为三类

  • 性能参数:用于JVM的性能调优和内存分配控制,如内存大小的设置
  • 行为参数:用于改变JVM的基础行为,如GC的方式和算法的选择
  • 调试参数:用于监控、打印、输出jvm的信息

不稳定参数语法规则

  • 布尔类型参数值:

    • -XX:+
    • -XX:- 示例:-XX:+UseG1GC,表示启用G1垃圾收集器
  • 数字类型参数值: -XX: 示例:-XX:MaxGCPauseMillis=500 ,表示设置GC的最大停顿时间是500ms

  • 字符串类型参数值: -XX: 示例:-XX:HeapDumpPath=./dump.core

6.4 常参数

–Xms4g -Xmx4g –Xmn1200m –Xss512k 
-XX:NewRatio=4 -XX:SurvivorRatio=8 -XX:MaxTenuringThreshold=15 
-XX:PermSize=100m -XX:MaxPermSize=256m 
-XX:MaxDirectMemorySize=1G -XX:+DisableExplicitGC

参数解析:

  • -Xms4g:初始化堆内存大小为4GB,ms是memory start的简称,等价于-XX:InitialHeapSize。
  • -Xmx4g:堆内存最大值为4GB,mx是memory max的简称,等价于-XX:MaxHeapSize。
  • -Xmn1200m:设置年轻代大小为1200MB。增大年轻代后,将会减小老年代大小。此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8
  • -Xss512k:设置每个线程的堆栈大小。JDK5.0以后每个线程堆栈大小为1MB,以前每个线程堆栈大小为256K。应根据应用线程所需内存大小进行调整。在相同物理内存下,减小这个值能生成更多的线程。但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经验值在3000~5000左右。
  • -XX:NewRatio=4:设置年轻代(包括Eden和两个Survivor区)与老年代的比值(除去持久代)。设置为4,则年轻代与老年代所占比值为1:4,年轻代占整个堆栈的1/5
  • -XX:SurvivorRatio=8:设置年轻代中Eden区与Survivor区的大小比值。设置为8,则两个Survivor区与个Eden区的比值为2:8,个Survivor区占整个年轻代的1/10
  • -XX:PermSize=100m:初始化永久代大小为100MB。
  • -XX:MaxPermSize=256m:设置持久代大小为256MB。
  • -XX:MaxTenuringThreshold=15:设置垃圾最大年龄。如果设置为0的话,则年轻代对象不经过Survivor区,直接进入老年代。对于老年代比较多的应用,可以提高效率。如果将此值设置为个较大值,则年轻代对象会在Survivor区进行多次复制,这样可以增加对象在年轻代的存活时间,增加在年轻代即被回收的概率。
  • -XX:MaxDirectMemorySize=1G:直接内存。报java.lang.OutOfMemoryError: Direct buffermemory异常可以上调这个值。
  • -XX:+DisableExplicitGC:禁止运行期显式地调用System.gc()来触发fulll GC。 注意: Java RMI的定时GC触发机制可通过配置-Dsun.rmi.dgc.server.gcInterval=86400来控制触发的时间。
  • -XX:CMSInitiatingOccupancyFraction=60:老年代内存回收阈值,默认值为68。
  • -XX:ConcGCThreads=4:CMS垃圾回收器并行线程线,推荐值为CPU核心数。
  • -XX:ParallelGCThreads=8:新生代并行收集器的线程数。
  • -XX:CMSMaxAbortablePrecleanTime=500:当abortable-preclean预清理阶段执行达到这个时间时就会结束。

*新生代、老年代、永久代的参数,如果不进性指定,虚拟机会子动选择合适的值,同时也会基于系统的开销自动调整*

6.4.1 -XX:+PrintFlagsInitial、-XX:+PrintFlagsFinal

Java 6(update 21oder 21之后)版本, HotSpot JVM 提供给了两个新的参数,在JVM启动后,在命令行中可以输出所有XX参数和值。 -XX:+PrintFlagsInitial:查看初始值 -XX:+PrintFlagsFinal:查看最终值(初始值可能被修改掉) 让我们现在就了解一下新参数的输出。以 -client 作为参数的 -XX:+ PrintFlagsFinal 的结果是一个按字母排序的590个参数表格(注意,每个release版本参数的数量会不一样)

img

18.png

表格的每一行包括五列,来表示一个XX参数。第一列表示参数的数据类型,第二列是名称,第四列为值,第五列是参数的类别。第三列”=”表示第四列是参数的默认值,而”:=” 表明了参数被用户或者JVM赋值了。

如果我们只想看下所有XX参数的默认值,能够用一个相关的参数,-XX:+PrintFlagsInitial 。 用 -XX:+PrintFlagsInitial , 只是展示了第三列为“=”的数据(也包括那些被设置其他值的参数)。

然而,注意当与-XX:+PrintFlagsFinal 对比的时候,一些参数会丢失,大概因为这些参数是动态创建的。

img

19.png

6.4.2 -XX:+PrintCommandLineFlags

让我们看下这个参数,事实上这个参数非常有用: -XX:+PrintCommandLineFlags 。这个参数让JVM打印出那些已经被用户或者JVM设置过的详细的XX参数的名称和值。

换句话说,它列举出 -XX:+PrintFlagsFinal的结果中第三列有":="的参数。以这种方式, 我们可以用-XX:+PrintCommandLineFlags作为快捷方式来查看修改过的参数。看下面的例子。

img

20.png

现在如果我们每次启动java 程序的时候设置 -XX:+PrintCommandLineFlags 并且输出到日志文件上,这样会记录下我们设置的JVM 参数对应用程序性能的影响。

6.4.3 GC日志相关

设置JVM GC格式日志的主要参数包括如下8个:

  1. -XX:+PrintGC 输出简要GC日志
  2. -XX:+PrintGCDetails 输出详细GC日志
  3. -Xloggc:gc.log 输出GC日志到文件
  4. -XX:+PrintGCTimeStamps 输出GC的时间戳(以JVM启动到当期的总时长的时间戳形式)
  5. -XX:+PrintGCDateStamps 输出GC的时间戳(以日期的形式,如 2020-04-26T21:53:59.234+0800)
  6. -XX:+PrintHeapAtGC 在进行GC的前后打印出堆的信息
  7. -verbose:gc : 在JDK 8中,-verbose:gc是-XX:+PrintGC一个别称,日志格式等价于:-XX:+PrintGC。不过在JDK 9中 -XX:+PrintGC被标记为deprecated。 -verbose:gc是一个标准的选项,-XX:+PrintGC是一个实验的选项,建议使用-verbose:gc 替代-XX:+PrintGC
  8. -XX:+PrintReferenceGC 打印年轻代各个引用的数量以及时长

开启GC日志 多种方法都能开启GC的日志功能,其中包括:使用-verbose:gc或-XX:+PrintGC这两个标志中的任意一个能创建基本的GC日志(这两个日志标志实际上互为别名,默认情况下的GC日志功能是关闭的)使用-XX:+PrintGCDetails标志会创建更详细的GC日志。 推荐使用-XX:+PrintGCDetails标志(这个标志默认情况下也是关闭的);通常情况下使用基本的GC日志很难诊断垃圾回收时发生的问题。

开启GC时间提示 除了使用详细的GC日志,我们还推荐使用-XX:+PrintGCTimeStamps或者-XX:+PrintGCDateStamps,便于我们更精确地判断几次GC操作之间的时间。这两个参数之间的差别在于时间戳是相对于0(依据JVM启动的时间)的值,而日期戳(date stamp)是实际的日期字符串。由于日期戳需要进性格式化,所以它的效率可能会受轻微的影响,不过这种操作并不频繁,它造成的影响也很难被我们感知。

指定GC日志路径 默认情况下GC日志直接输出到标准输出,不过使用-Xloggc:filename标志也能修改输出到某个文件。除了显式地使用-PrintGCDetails标志,否则使用-Xloggc会自动地开启基本日志模式。

使用日志循环(Log rotation)标志可以限制保存在GC日志中的数据量;对于需要长时间运行的服务器而言,这是一个非常有用的标志,否则累积几个月的数据很可能会耗尽服务器的磁盘。

开启日志滚动输出 通过-XX:+UseGCLogfileRotation -XX:NumberOfGCLogfiles=N -XX:GCLogfileSize=N标志可以控制日志文件的循环。 默认情况下,UseGCLogfileRotation标志是关闭的。它负责打开或关闭GC日志滚动记录功能的。要求必须设置 -Xloggc参数开启UseGCLogfileRotation标志后,默认的文件数目是0(意味着不作任何限制),默认的日志文件大小是0(同样也是不作任何限制)。因此,为了让日志循环功能真正生效,我们必须为所有这些标志设定值。

需要注意的是:

  • 设置滚动日志文件的大小,必须大于8k。当前写日志文件大小超过该参数值时,日志将写入下一个文件
  • 设置滚动日志文件的个数,必须大于等于1
  • 必须设置 -Xloggc 参数

开启语句

-XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:/home/hadoop/gc.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=512k

其他有用参数 -XX:+PrintGCApplicationStoppedTime 打印GC造成应用暂停的时间 -XX:+PrintTenuringDistribution 在每次新生代 young GC时,输出幸存区中对象的年龄分布

日志含义

img

21.png

img

22.png

6.4.4 -XX:CMSFullGCsBeforeCompaction

CMSFullGCsBeforeCompaction 说的是,在上一次CMS并发GC执行过后,到底还要再执行多少次full GC才会做压缩。默认是0,也就是在默认配置下每次CMS GC顶不住了而要转入full GC的时候都会做压缩。 如果把CMSFullGCsBeforeCompaction配置为10,就会让上面说的第一个条件变成每隔10次真正的full GC才做一次压缩(而不是每10次CMS并发GC就做一次压缩,目前VM里没有这样的参数)。这会使full GC更少做压缩,也就更容易使CMS的old gen受碎片化问题的困扰。 本来这个参数就是用来配置降低full GC压缩的频率,以期减少某些full GC的暂停时间。CMS回退到full GC时用的算法是mark-sweep-compact,但compaction是可选的,不做的话碎片化会严重些但这次full GC的暂停时间会短些。这是个取舍。

-XX:+UseCMSCompactAtFullCollection
-XX:CMSFullGCsBeforeCompaction=10

两个参数必须同时使用才能生效。

6.4.5 -XX:HeapDumpPath

堆内存出现OOM的概率是所有内存耗尽异常中最高的,出错时的堆内信息对解决问题非常有帮助,所以给JVM设置这个参数(-XX:+HeapDumpOnOutOfMemoryError),让JVM遇到OOM异常时能输出堆内信息,并通过(-XX:+HeapDumpPath)参数设置堆内存溢出快照输出的文件地址,这对于特别是对相隔数月才出现的OOM异常来说尤为重要。 这两个参数通常配套使用:

-XX:+HeapDumpOnOutOfMemoryError 
-XX:HeapDumpPath=./

6.4.6 -XX:OnOutOfMemoryError

-XX:OnOutOfMemoryError=
"/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/binjconsole"

表示发生OOM后,运行jconsole程序。这里可以不用加“”,因为jconsole.exe路径Program Files含有空格。

利用这个参数,我们可以在系统OOM后,自定义一个脚本,可以用来发送邮件告警信息,可以用来重启系统等等。

6.4.7 XX:InitialCodeCacheSize

JVM一个有趣的,但往往被忽视的内存区域是“代码缓存”,它是用来存储已编译方法生成的本地代码。代码缓存确实很少引起性能问题,但是一旦发生其影响可能是毁灭性的。如果代码缓存被占满,JVM会打印出一条警告消息,并切换到interpreted-only 模式:JIT编译器被停用,字节码将不再会被编译成机器码。因此,应用程序将继续运行,但运行速度会降低一个数量级,直到有人注意到这个问题。

就像其他内存区域一样,我们可以自定义代码缓存的大小。相关的参数是-XX:InitialCodeCacheSize 和- XX:ReservedCodeCacheSize,它们的参数和上面介绍的参数一样,都是字节值。

6.4.8 -XX:+UseCodeCacheFlushing

如果代码缓存不断增长,例如,因为热部署引起的内存泄漏,那么提高代码的缓存大小只会延缓其发生溢出。

为了避免这种情况的发生,我们可以尝试一个有趣的新参数:当代码缓存被填满时让JVM放弃一些编译代码。通过使用-XX:+UseCodeCacheFlushing 这个参数,我们至少可以避免当代码缓存被填满的时候JVM切换到interpreted-only 模式。

不过,我仍建议尽快解决代码缓存问题发生的根本原因,如找出内存泄漏并修复它。

在这里插入图片描述

结语

如果这篇文章对您有所帮助,或者有所启发的话,求一键三连:点赞、评论、收藏➕关注,您的支持是我坚持写作最大的动力。

Jvm调优和SpringBoot项目优化的详细教程
09-07
JVM调优和SpringBoot项目优化是提升应用性能和稳定性的关键环节。首先,我们要了解JVMJava Virtual Machine)调优的基本概念。JVM作为Java应用程序的运行环境,其性能直接影响程序的运行效率。调优主要包括调整堆...
基于jdk17JVM GC配置详解
从小看天书
11-12 3919
本文章基于Oracle官方文档编写,翻译有误的欢迎指正。
JVM 17调优指南:如何进行JVM调优JVM调优参数
哈利路亚的收藏夹
01-11 1632
JVM调优是调整和配置Java虚拟机(JVM)的过程,以便最大限度地提高应用程序的性能和效率。这涉及到调整内存设置、选择合适的垃圾收集器,以及配置各种性能参数。通过上述示例,我们可以看到JVM调优是一个多方面的过程,涉及不同层面的调整和配置。合理使用JVM调优参数,可以帮助我们更好地理解和优化Java应用程序的性能。希望这些示例能够帮助你在实际工作中更有效地进行JVM调优。每个Java应用程序都是独一无二的,因此最佳的JVM调优参数组合可能因应用而异。
JVMJVM 实战调优指南赋案例(保姆篇)
最新发布
A的博客
08-16 1192
即时编译器(JIT)将字节码编译为机器码,以提高运行时性能。热点编译(HotSpot Compilation):编译热点代码,提高执行效率。逃逸分析(Escape Analysis):优化对象的内存分配和回收。
Java应用的GC优化
zzhongcy的专栏
09-26 677
最近看到这篇GC优化,自己标记一下,这里记录学习! Java应用的GC优化 当Java程序性能达不到既定目标,且其他优化手段都已经穷尽时,通常需要调整垃圾回收器来进一步提高性能,称为GC优化。但GC算法复杂,影响GC性能的参数众多,且参数调整又依赖于应用各自的特点,这些因素很大程度上增加了GC优化的难度。即便如此,GC调优也不是无章可循,仍然有一些通用的思考方法。本篇会介绍这些通用...
我所使用的生产 Java 17 启动参数
hashcon
06-15 3917
目前正常微服务综合内存占用+延迟+吞吐量,还是 G1 更优秀。但是如果你的微服务本身压力没到机器极限,要求延迟低,那么 ZGC 最好。如果你是实现数据库那样的需求(大量缓存对象,即长时间生存对象,老年代很大,并且还会可能分配大于区域的对象),那么必须使用 ZGC。使用 G1GC 启动参数: 使用 ZGC 启动参数: 其中,需要做成环境变量外部可以配置的是:JVM 日志配置请参考:https://zhuanlan.zhihu.com/p/111886882以下需要做成可以在外部配置的环境变量:除了以上内存,J
jvm的那些设置参数你都知道吗
SimpleSmile_5177
01-15 721
前言 大家都知道,jvm在启动的时候,会执行默认的一些参数。一般情况下,这些设置的默认参数应对一些平常的项目也够用了。但是如果项目特别大了,需要增加一下堆内存的大小、或者是系统老是莫明的挂掉,想查看下gc日志来排查一下错误的原因,都需要咱们手动设置这些参数。 各个参数介绍 1.verbose:gc 表示,启动jvm的时候,输出jvm里面的gc信息。格式如下: [Full GC 178K...
java JDK17 jvm参数配置示例及解读
学亮编程手记
05-26 1264
包的访问权限,允许未命名模块(通常是那些没有声明属于任何模块的类路径上的类)访问这个包内的元素。指定使用Z Garbage Collector(ZGC),这是一个可伸缩、低延迟的垃圾收集器,特别适合大规模的多核系统,旨在实现暂停时间不超过10毫秒的目标。整体而言,这些配置旨在优化一个应用的内存管理、垃圾收集策略,以及提升在遇到内存问题时的诊断能力,特别是针对需要高性能、低延迟处理的应用场景。控制内存分配速率突增的容忍度,值越高,JVM越晚响应突增的内存需求,以避免不必要的垃圾回收。)和最大堆内存大小(
查看 JVM 默认参数值命令
chuhui1765的博客
11-23 903
本人使用环境: win7 ( 64位) + jdk 8 主要使用命令: > java -XX:+PrintFlagsFinal -version 本人环境信息: C:\Users\Administrator> java -XX:+Prin...
JVM调优实践 ⼀、JVM调优准备⼯作 实验报告 pdf
01-02
Java虚拟机(JVM)是Java程序运行的基础,它的调优是提高应用程序性能的关键环节。在JVM调优实践中,了解各个运行时数据区的工作原理至关重要。以下是对这些区域的详细解析: 1. **虚拟机栈**:每个线程都有一个...
JVM调优前戏之JDK命令行工具.docx
11-24
JVM调优前戏之JDK命令行工具 JVM调优前戏之JDK命令行工具是JDK中的一组命令行工具,用于监测JVM运行时的状态。这些工具对于普通开发人员来说可能不太熟悉,但它们却是JVM调优的重要步骤。在这篇文章中,我们将详细...
JVM 调优之 Eclipse 启动调优实战
12-21
**JVM调优实战——Eclipse启动调优** 在Java开发中,Eclipse作为常用的集成开发环境,其启动速度和运行效率对开发者的工作效率有着直接影响。本文将分享一个基于旧版环境(Dell E5410,Intel i3 CPU M 370,2GB内存...
JVM调优总结.doc
09-13
"JVM调优总结" JVM调优是一种非常重要的技术,能够帮助我们提高Java应用程序的性能和稳定性。在这篇文章中,我们将总结JVM调优的一些基本概念和算法。 一、相关概念 JVM调优的基本概念包括引用计数、标记-清除、...
JVM 11 的优化指南:如何进行JVM调优JVM调优参数有哪些
程序员Linc
07-22 2123
在实际的Java应用开发中,JVMJava Virtual Machine)调优是提升应用性能的关键步骤。合理的调优可以显著提升应用的响应速度、吞吐量,并且减少内存消耗和GC(Garbage Collection)停顿时间。本文将详细介绍JVM 11的优化指南,包含如何进行JVM调优以及常见的JVM调优参数,并提供3个实用的代码示例。
Java 11 到 Java 17 的最佳 HotSpot JVM 选项和开关
hnjsjsac的博客
10-13 1720
一、前言 在本文中,你将了解 OpenJDK HotSpot Java 虚拟机 (HotSpot JVM) 中的一些系统知识,以及如何调整它们以获得最佳状态适应你的程序和运行环境。HotSpot JVM 是一项了不起且灵活的技术。它作为二进制版本适用于每个主要操作系统和 CPU 架构,从微型 Raspberry Pi Zero 一直到包含数百个 CPU 内核和 TB RAM 的“大型”服务器。由于 OpenJDK 是一个开源项目,HotSpot JVM 几乎可以针对任何其他系统进行编译,并且可以使用选项
Java17优化指南
升仔聊编程的博客
01-16 1132
JAVA17
垃圾回收器
qq_44346427的博客
04-12 382
垃圾回收器
17.JVM性能调优
weixin_43613968的博客
05-05 209
JVM性能调优是通过调整JVM参数来优化应用程序的性能。总之,JVM性能调优需要根据应用程序的特点和需求来选择适当的优化策略,并进行测试和调整。
从实际出发记一次优化⭐《G1、JDK17、Flux性能调优》⭐
qq_35040959的博客
11-07 987
本文从实际项目出发记录一次项目性能调优,很多时候都是无效优化,但学习过程十分有意义
jdk8 jvm调优 xmn
08-24
对于JDK 8的JVM调优,其中一个关键的参数是-Xmn。-Xmn参数用于设置新生代的大小,新生代是JVM内存分配中的一部分,用于存放新创建的对象。调整新生代的大小可以影响垃圾回收性能和内存使用效率。 默认情况下,JDK 8中的新生代大小是整个堆内存的1/3。如果你想调整新生代的大小,可以使用-Xmn参数加上指定的数值来设置。例如,-Xmn256m表示将新生代的大小设置为256MB。 调整新生代的大小需要根据具体应用程序的需求和环境进行实验和调整。一般来说,如果应用程序有很多短期存活的对象,可以考虑增大新生代的大小以减少垃圾回收的频率。反之,如果应用程序有很多长期存活的对象,可以考虑减小新生代的大小以提高内存使用效率。 除了调整-Xmn参数,还可以通过其他参数来进一步调优JVM,如调整堆大小(-Xms和-Xmx)、选择垃圾回收算法(-XX:+UseParallelGC或-XX:+UseG1GC)等。但是,请注意在调优时要谨慎进行,并且进行充分的测试和性能监控,以确保调优的效果和稳定性。
写文章

热门文章

  • 关于猫头虎,认识猫头虎,建联猫头虎,商务合作,产品评测,产品推广,个人自媒体创作,超级个体,涨粉秘籍,一起探索编程世界的无限可能! 101970
  • 云原生技术社区简介 100180
  • 100天精通鸿蒙从入门到跳槽——第0天:Web/安卓开发者的鸿蒙之旅 73394
  • 100天精通鸿蒙从入门到跳槽——第1天:从安装编译器 DevEco Studio 开始 72742
  • 2022 最新 IntelliJ IDEA 详细配置步骤演示(图文版) 70053

分类专栏

  • 100天精通HarmonyOS:Web开发者的鸿蒙之旅 付费 22篇
  • 优质全栈工具类专栏 付费 20篇
  • 猫头虎 AI 探索之路 39篇
  • 猫头虎分享AI时代新名词解释 1篇
  • AI人工智能技术专栏 102篇
  • 猫头虎分享21天微信小程序基础入门教程 23篇
  • 100天精通Golang基础入门专栏 27篇
  • 猫头虎精品博客专栏 18篇
  • IPV4 To IPV6 攻略大全 20篇
  • Golang技术专区 237篇
  • Go生态洞察 234篇
  • 云原生技术专区 85篇
  • 微服务专栏 34篇
  • 容器技术专栏 39篇
  • Spring全家桶技术专区 42篇
  • SpringCloud 专栏 17篇
  • SpringBoot专栏 54篇
  • 数据库技术专区 20篇
  • PostgreSQL专栏 28篇
  • MySQL专栏 58篇
  • Redis专栏 30篇
  • 高效办公工具专区 129篇
  • IDEA专栏 86篇
  • Git专栏 23篇
  • Java技术专区 136篇
  • JDK新特性专栏 23篇
  • 后端技术专区 34篇
  • Python专栏 57篇
  • 前端技术专区 66篇
  • 运维技术专区 92篇
  • Linux专栏 108篇
  • 服务器专栏 43篇
  • 职场与发展专区 50篇
  • 全栈面试题大全专栏 131篇
  • 前沿技术专区 71篇

最新评论

  • 猫头虎分享:Python库 Redis-Py 的简介、安装、用法详解入门教程

    陈橘又青: 博主的文章细节很到位,兼顾实用性和可操作性,感谢博主的分享,期待博主持续带来更多好文,同时也希望可以来我博客指导我一番!

  • 猫头虎分享:Python库 PyMongo 的简介、安装、用法详解入门教程

    码踏云端: 博主的文章总是如一盏明灯,指引我前进,每一篇博文都是一次心灵的提升,你的分享总是如此珍贵,你的博文总是让我拓展了视野,增长了见识,感谢你一直以来的无私奉献。期待更多知识的分享。非常感激你的专业知识传授。

  • 腾讯云AI代码助手评测:如何智能高效完成Go语言Web项目开发

    青云交: 您好!有幸拜读了您的文章,顿觉如获至宝。文中细节之处的分析可谓丝丝入扣、精妙绝伦,实用性更是首屈一指。在此,我衷心地向您表达最诚挚的感谢,感谢您的无私奉献与倾心分享。我已对您的文章给予了点赞、收藏、评论三连支持,以表我对其的喜爱与赞赏。真心期待您能够持之以恒地输出高质量的精彩美文,继续为我们带来知识的盛宴与思想的启迪。同时,我热烈欢迎博主莅临我的小站一坐,共同交流探讨,分享彼此的心得与感悟。再次向您致以最崇高的敬意和最诚挚的谢意!

  • 猫头虎分享:Python库 Pandas 的简介、安装、用法详解入门教程

    猫头虎: 猫头虎在此感谢表情包正在走向自律大佬的阅读和支持! 您的阅读反馈是我继续前行的理由,🌈🐅🚀 遇到学习或创作的问题,请随时私信我、Libin9iOak或CaracalTiger。💖💌

  • 猫头虎分享:Python库 Pandas 的简介、安装、用法详解入门教程

    猫头虎: 猫头虎在此感谢表情包帅次大佬的阅读和支持! 您的阅读反馈是我继续创作的动力,🌈🐅 如果您在创作和学习过程中有任何疑问,欢迎私信我或Libin9iOak或者CaracalTiger。🚀💌

最新文章

  • 猫头虎 分享:Python库 Bottle 的简介、安装、用法详解入门教程
  • 猫头虎分享:Python库 Redis-Py 的简介、安装、用法详解入门教程
  • 猫头虎分享:Python库 Pandas 的简介、安装、用法详解入门教程
2024
09月 25篇
08月 63篇
07月 49篇
06月 58篇
05月 68篇
04月 64篇
03月 36篇
02月 64篇
01月 43篇
2023年999篇
2022年236篇
2021年209篇
2020年39篇

目录

目录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猫头虎

一分也是爱,打赏博主成就未来!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或 充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值

深圳SEO优化公司寿光优化网站价格网站云优化工具大庆专业网站seo优化费用石家庄网站关键词优化排名靠谱的电商网站优化价格优惠沈阳快速网站优化廊坊低价婚纱摄影网站优化泉州网站技术优化菏泽网站优化方案衢州网站优化平台焦作律师网站优化根河网站优化保定网站搜索排名优化哪家好保定优化网站方法合肥网站优化步骤阜宁网站优化公司网站优化怎么获取内容封开网站搜索引擎优化沙田新能源网站优化安阳网络推广优化网站海口湖南网站优化推广淄博济南网站优化时间天镇县网站seo优化排名河南郑州网站优化方案寻找网站优化推广一站式服务江门网站首页关键词优化多少钱奉贤网站优化乐亭网站优化联系方式自贡网站排名优化服务东台网站优化找哪家好歼20紧急升空逼退外机英媒称团队夜以继日筹划王妃复出草木蔓发 春山在望成都发生巨响 当地回应60岁老人炒菠菜未焯水致肾病恶化男子涉嫌走私被判11年却一天牢没坐劳斯莱斯右转逼停直行车网传落水者说“没让你救”系谣言广东通报13岁男孩性侵女童不予立案贵州小伙回应在美国卖三蹦子火了淀粉肠小王子日销售额涨超10倍有个姐真把千机伞做出来了近3万元金手镯仅含足金十克呼北高速交通事故已致14人死亡杨洋拄拐现身医院国产伟哥去年销售近13亿男子给前妻转账 现任妻子起诉要回新基金只募集到26元还是员工自购男孩疑遭霸凌 家长讨说法被踢出群充个话费竟沦为间接洗钱工具新的一天从800个哈欠开始单亲妈妈陷入热恋 14岁儿子报警#春分立蛋大挑战#中国投资客涌入日本东京买房两大学生合买彩票中奖一人不认账新加坡主帅:唯一目标击败中国队月嫂回应掌掴婴儿是在赶虫子19岁小伙救下5人后溺亡 多方发声清明节放假3天调休1天张家界的山上“长”满了韩国人?开封王婆为何火了主播靠辱骂母亲走红被批捕封号代拍被何赛飞拿着魔杖追着打阿根廷将发行1万与2万面值的纸币库克现身上海为江西彩礼“减负”的“试婚人”因自嘲式简历走红的教授更新简介殡仪馆花卉高于市场价3倍还重复用网友称在豆瓣酱里吃出老鼠头315晚会后胖东来又人满为患了网友建议重庆地铁不准乘客携带菜筐特朗普谈“凯特王妃P图照”罗斯否认插足凯特王妃婚姻青海通报栏杆断裂小学生跌落住进ICU恒大被罚41.75亿到底怎么缴湖南一县政协主席疑涉刑案被控制茶百道就改标签日期致歉王树国3次鞠躬告别西交大师生张立群任西安交通大学校长杨倩无缘巴黎奥运

深圳SEO优化公司 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化