学习笔记-JVM-工具包(JVM分析工具)

这篇具有很好参考价值的文章主要介绍了学习笔记-JVM-工具包(JVM分析工具)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

常用工具

JDK工具

① jps: JVM Process status tool:JVM进程状态工具,查看进程基本信息
② jstat: JVM statistics monitoring tool : JVM统计监控工具,查看堆,GC详细信息
③ jinfo:Java Configuration Info :查看配置参数信息,支持部分参数运行时修改
④ jmap:Java Memory Map :分析堆内存工具,dump堆内存快照
⑤ jhat:Java Heap Analysis Tool :堆内存dump文件解析工具
⑥ jstack:Java Stack Trace :Java堆栈跟踪工具
⑦ VisualVM:性能分析可视化工具
注:前面6个为命令行,最后一个为性能分析可视化工具(不能在linux中使用)

第三方工具

① GCEasy:免费GC日志可视化分析Web工具
② MAT:Memory Analyzer Tool 可视化内存分析工具
③ GCViewer:开源的GC日志分析工具
④ Arthas:线上Java程序诊断工具,功能非常强大

JDK工具使用案例
  1. JPS
#列出Java程序进程ID和Main函数名称
jps 

#只输出进程ID
jps -q 

#输出传递给Java进程(主函数)的参数 例如--spring.config.location
jps -m 

#输出主函数的完整路径
jps -l 

#显示传递给Java虚拟的参数
jps -v 
  1. jstat

options:由以下值构成
-class:显示ClassLoader的相关信息
-compiler:显示JIT编译的相关信息
-gc:显示与GC相关信息
-gccapacity:显示各个代的容量和使用情况
-gccause:显示垃圾收集相关信息(同-gcutil),同时显示最后一次或当前正在发生的垃圾收集的诱发原因
-gcnew:显示新生代信息
-gcnewcapacity:显示新生代大小和使用情况
-gcold:显示老年代信息
-gcoldcapacity:显示老年代大小
-gcpermcapacity:显示永久代大小
-gcutil:显示垃圾收集信息

#进程id 采样间隔250ms 采样数4
jstat -gc 30108 250 4

学习笔记-JVM-工具包(JVM分析工具),学习笔记,Java,学习,笔记,jvm,分析工具,jvm分析

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:metaspace的容量 (单位kb)
MU:metaspace目前已使用空间 (单位kb)
CCSC:压缩类空间大小
CCSU:压缩类空间使用大小
YGC :从应用程序启动到采样时年轻代中gc次数
YGCT :从应用程序启动到采样时年轻代中gc所用时间(s)
FGC :从应用程序启动到采样时old代(全gc)gc次数
FGCT :从应用程序启动到采样时old代(全gc)gc所用时间(s)
GCT:从应用程序启动到采样时gc用的总时间(s)

#进程ID 26856 采样间隔1s 采样数5
jstat -gcutil 26856 1s 5

学习笔记-JVM-工具包(JVM分析工具),学习笔记,Java,学习,笔记,jvm,分析工具,jvm分析
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)

  1. jinfo
    -flags 打印虚拟机 VM 参数
    -flag 打印指定虚拟机 VM 参数
    -flag [+|-] 打开或关闭虚拟机参数
    -flag = 设置指定虚拟机参数的值
#参数选项 进程id
jinfo -flags 26856

学习笔记-JVM-工具包(JVM分析工具),学习笔记,Java,学习,笔记,jvm,分析工具,jvm分析

  1. Jmap
    用来查看堆内存的使用情况,一般结合jhat使用。
jmap 26856 #进程号

查看进程的内存映像信息。使用不带选项参数的jmap打印共享对象映射,将会打印目标虚拟机中加载的每个共享对象的
起始地址、映射大小以及共享对象文件的路径全称。
学习笔记-JVM-工具包(JVM分析工具),学习笔记,Java,学习,笔记,jvm,分析工具,jvm分析

#显示Java堆详细信息:打印堆的摘要信息,包括使用的GC算法、堆配置信息和各内存区域内存使用信息
jmap -heap 26856 

学习笔记-JVM-工具包(JVM分析工具),学习笔记,Java,学习,笔记,jvm,分析工具,jvm分析

jmap -histo:live 26856 

显示堆中对象的统计信息:其中包括每个Java类、对象数量、内存大小(单位:字节)、完全限定的类名。打印的虚拟机内部的类名称将会带有一个’*’前缀。如果ja指定了live子选项,则只计算活动的对象。
学习笔记-JVM-工具包(JVM分析工具),学习笔记,Java,学习,笔记,jvm,分析工具,jvm分析

jmap -clstats 26856

打印类加载器信息:打印Java堆内存的方法区的类加载器的智能统计信息。对于每个类加载器而言,它的名称、活跃度、
地址、父类加载器、它所加载的类的数量和大小都会被打印。此外,包含的字符串数量和大小也会被打印。
学习笔记-JVM-工具包(JVM分析工具),学习笔记,Java,学习,笔记,jvm,分析工具,jvm分析

jmap -finalizerinfo 26856 #打印等待终结的对象信息
jmap -dump:format=b,file=heapdump.hprof 26856 

生成堆转储快照dump文件:以二进制格式转储Java堆到指定文件中。如果指定了live子选项,堆中只有活动的对象会被转
储。浏览heap dump 可以使用jhat 读取生成的文件,也可以使用MAT等堆内存分析工具。
注意:这个命令执行,JVM会将整个heap的信息dump写入到一个文件,heap如果比较大的话,就会导致这个过程比较耗时,并且执
行的过程中为了保证dump的信息是可靠的,所以会暂停应用, 线上系统慎用!
5. Jhat :Java Heap Analysis Tool
jhat 命令会解析Java堆转储文件,并启动一个 web server。然后用浏览器来查看/浏览 dump 出来的 heap二进制文件。
jhat 命令支持预先设计的查询,比如:显示某个类的所有实例。还支持 对象查询语言(OQL)。 OQL有点类似SQL,专门用来
查询堆转储。
Java生成堆转储的方式有多种:

  1. 使用 jmap -dump 选项可以在JVM运行时获取 dump.
  2. 使用 jconsole 选项通过 HotSpotDiagnosticMXBean 从运行时获得堆转储。
  3. 在虚拟机启动时如果指定了 -XX:+HeapDumpOnOutOfMemoryError 选项,则抛出 OutOfMemoryError 时,会自动执行堆转
    储。
jhat [ options ] heap-dump-file
jmap -dump:format=b,file=demo.hprof 26856 

jhat ./demo.hprof #可以启动一个服务端口是7000 查看堆的信息

学习笔记-JVM-工具包(JVM分析工具),学习笔记,Java,学习,笔记,jvm,分析工具,jvm分析

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)

  1. jstack:Java Stack Trace
    jstack是Java虚拟机自带的一种堆栈跟踪工具,用于生成java虚拟机当前时刻的线程快照。
    线程快照是当前Java虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的是定位线程出现长时间停顿的原因,
    如线程间死锁、死循环、请求外部资源导致的长时间等待、等等。
    线程快照里留意下面几种状态
    死锁,Deadlock(重点关注)
    等待资源,Waiting on condition(重点关注)
    等待获取管程,Waiting on monitor entry(重点关注)
    阻塞,Blocked(重点关注)
    执行中,Runnable
    暂停,Suspended
    对象等待中,Object.wait() 或 TIMED_WAITING
    停止,Parked
jstack [ option ] pid #查看当前时间点,指定进程的dump堆栈信息。
jstack [ option ] pid > #文件 将当前时间点的指定进程的dump堆栈信息,写入到指定文件中。
# 注:若该文件不存在,则会自动生成; 若该文件存在,则会覆盖源文件。
jstack [ option ] executable core# 查看当前时间点,core文件的dump堆栈信息。
jstack [ option ] [server_id@]<remote server IP or hostname> #查看当前时间点,远程机器的dump堆栈信息。

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

jstack 26856 #打印堆栈
jstack -l 26856 | grep 'java.lang.Thread.State' | wc -l 统计线程数量

学习笔记-JVM-工具包(JVM分析工具),学习笔记,Java,学习,笔记,jvm,分析工具,jvm分析

  1. VisualVM
    VisualVM 是一款免费的性能分析工具。它通过 jvmstat、JMX、SA(Serviceability Agent)以及 Attach API 等多种方式从程序运行时
    获得实时数据,从而进行动态的性能分析。同时,它能自动选择更快更轻量级的技术尽量减少性能分析对应用程序造成的影响,提高
    性能分析的精度。
    远程可视化监控JVM
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=9999
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false
-Djava.rmi.server.hostname=172.26.233.198
-Dcom.sun.management.jmxremote.rmi.port=9999
#JAVA_OPT="${JAVA_OPT} -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9999 -
Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -
Djava.rmi.server.hostname=123.56.254.18 -Dcom.sun.management.jmxremote.rmi.port=9999"

需要互联需要在同一网段才能使用,连公网ip是不可以的。
学习笔记-JVM-工具包(JVM分析工具),学习笔记,Java,学习,笔记,jvm,分析工具,jvm分析

第三方工具使用案例
  1. GCEasy
    业界首先采用机器学习算法解决GC日志分析问题,GCeasy内置机器智能可以自动检测JVM和Android GC日志中的问题,并推荐解决
    方案。
    https://gceasy.io/
    GC日志分析是免费的,Machine Learning收费,它的使用只需要在网站上上传一个gc日志。
    特点:
    几秒内解决GC和内存问题
    提供JVM堆优化建议
    基于机器学习
    学习笔记-JVM-工具包(JVM分析工具),学习笔记,Java,学习,笔记,jvm,分析工具,jvm分析

学习笔记-JVM-工具包(JVM分析工具),学习笔记,Java,学习,笔记,jvm,分析工具,jvm分析
2. MAT
1)介绍
MAT是一个强大的可视化内存分析工具,可以快捷、有效地帮助我们找到内存泄露,减少内存消耗分析工具。MAT是Memory
Analyzer tool的缩写,是一种快速,功能丰富的Java堆分析工具,能帮助你查找内存泄漏和减少内存消耗。
功能:
找到最大的对象,因为MAT提供显示合理的累积大小(retained size)
探索对象图,包括inbound和outbound引用,即引用此对象的和此对象引出的
查找无法回收的对象,可以计算从垃圾收集器根到相关对象的路径
找到内存浪费,比如冗余的String对象,空集合对象。
MAT下载地址
注意需要下载支持JDK的版本:
学习笔记-JVM-工具包(JVM分析工具),学习笔记,Java,学习,笔记,jvm,分析工具,jvm分析
学习笔记-JVM-工具包(JVM分析工具),学习笔记,Java,学习,笔记,jvm,分析工具,jvm分析
学习笔记-JVM-工具包(JVM分析工具),学习笔记,Java,学习,笔记,jvm,分析工具,jvm分析

MAT相关概念说明
1 内存泄漏与内存溢出
内存泄露:对象是垃圾了,还存在被GCRoots引用的情况,无法被垃圾收集器回收。
解决方案:找出泄漏的代码位置和原因,具体问题具体解决;
内存溢出:内存中的对象非常多,堆空间不足,就会出现。
解决方案:检查堆大小设置是否合理,检查是否存在对象生命周期太长、持有状态时间过长的情况。
2 shallow heap及retained heap
shallow heap:对象本身占用内存的大小,也就是对象内存区域的总和。
retained heap:对象及对象引用链中所有对象的大小总和,如果一个对象被释放掉,因为该对象的释放而被释放的所有的对象
的大小。相对于shallow heap,Retained heap可以更精确的反映一个对象实际占用的大小。
3 outgoing references与incoming references
outgoing references :表示该对象的出节点(被该对象引用的对象)。
incoming references :表示该对象的入节点(引用到该对象的对象)。
3 Dominator Tree
Dominator Tree对象的支配树:帮助我们快速的发现占用内存最大的块,也能帮我们分析对象之间的依赖关系。
学习笔记-JVM-工具包(JVM分析工具),学习笔记,Java,学习,笔记,jvm,分析工具,jvm分析
分析GC
学习笔记-JVM-工具包(JVM分析工具),学习笔记,Java,学习,笔记,jvm,分析工具,jvm分析

MAT工具使用
分析内存溢出
分析内存泄露
查看对象个数及对象内存占用
观察对象回收后释放空间大小
观察线程栈

  1. GCViewer
    GCViewer是一款开源的GC日志分析工具。项目的 GitHub 主页对各个指标提供了完整的描述信息 需要安装JDK才能使用。借助
    GCViewer日志分析工具,可以非常直观地分析出待调优点。
    可从以下几方面来分析:
    Memory:分析Totalheap、Tenuredheap、Youngheap内存占用率及其他指标,理论上内存占用率越小越好;
    Pause:分析Gc pause、Fullgc pause、Total pause三个大项中各指标,理论上GC次数越少越好,GC时长越小越好;
    下载地址GCeasy的替代品
 #分析gc日志,打开图形化界面
java -jar gcviewer-1.36.jar gc.log
# 分析gc日志,不打卡图形化界面,将结果直接生成
java -jar gcviewer-1.36.jar gc.log summary.csv chart.png
  1. Arthas
    Arthas 是一款线上监控诊断产品,通过全局视角实时查看应用 load、内存、gc、线程的状态信息,并能在不修改应用代码的情况下,
    对业务问题进行诊断,包括查看方法调用的出入参、异常,监测方法执行耗时,类加载信息等,大大提升线上问题排查效率。
    可以做什么?
    当你遇到以下类似问题而束手无策时, Arthas 可以帮助你解决:
    1 这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception?
    2 我改的代码为什么没有执行到?难道是我没 commit?分支搞错了?
    3 遇到问题无法在线上 debug,难道只能通过加日志再重新发布吗?
    4 线上遇到某个用户的数据处理有问题,但线上同样无法 debug,线下无法重现!
    5 是否有一个全局视角来查看系统的运行状况?
    6 有什么办法可以监控到 JVM 的实时运行状态?
    7 怎么快速定位应用的热点,生成火焰图?
    Arthas 支持 JDK 6+,支持 Linux、Mac、Winodws,采用命令行交互模式,同时提供丰富的 Tab 自动补全功能,进一步方便进行问
    题的定位和诊断。
# 下载arthas-boot.jar
curl -O https://alibaba.github.io/arthas/arthas-boot.jar
# 打印帮助信息:
java -jar arthas-boot.jar -h
# 启动
java -jar arthas-boot.jar

Arthas 常见命令
jvm:查看当前 JVM 的信息
thread:查看当前 JVM 的线程堆栈信息,
-b 选项可以一键检测死锁
-n 指定最忙的前N个线程并打印堆栈
-1 打印统计信息(数字1)
trace:方法内部调用路径,并输出方法路径上的每个节点上耗时,服务间调用时间过长时使用
stack:输出当前方法被调用的调用路径
Jad:反编译指定已加载类的源码,反编译便于理解业务
logger:查看和修改 logger,可以动态更新日志级别
支持管道:
Arthas支持使用管道对上述命令的结果进行进一步的处理,如 sm java.lang.String * | grep ‘index’
grep——搜索满足条件的结果
plaintext——将命令的结果去除ANSI颜色
wc——按行统计输出结果
后台异步任务:
当线上出现偶发的问题,比如需要watch某个条件,而这个条件一天可能才会出现一次时,异步后台任务就派上用场了,详情请参考
这里
使用 > 将结果重写向到日志文件,使用 & 指定命令是后台运行,session断开不影响任务执行(生命周期默认为1天)
jobs——列出所有job
kill——强制终止任务
fg——将暂停的任务拉到前台执行
bg——将暂停的任务放到后台执行
用户数据回报:
在 3.1.4 版本后,增加了用户数据回报功能,方便统一做安全或者历史数据统计。
在启动时,指定 stat-url ,就会回报执行的每一行命令,比如: ./as.sh --stat-url
‘http://192.168.10.11:8080/api/stat’
在tunnel server里有一个示例的回报代码,用户可以自己在服务器上实现
这里只列出常用命令,完整列表参考命令列表:https://github.com/alibaba/arthas/blob/master/README_CN.md

使用
学习笔记-JVM-工具包(JVM分析工具),学习笔记,Java,学习,笔记,jvm,分析工具,jvm分析

dashboard

学习笔记-JVM-工具包(JVM分析工具),学习笔记,Java,学习,笔记,jvm,分析工具,jvm分析

thread -1 #会打印线程统计信息 这里是数字1

学习笔记-JVM-工具包(JVM分析工具),学习笔记,Java,学习,笔记,jvm,分析工具,jvm分析

jap com.learn.lessonone.DemoController #反编译源码

学习笔记-JVM-工具包(JVM分析工具),学习笔记,Java,学习,笔记,jvm,分析工具,jvm分析

 watch com.learn.lessonone.DemoController  getData returnObj#监控接口 controller getData是方法名,注意是方法名不是路径

学习笔记-JVM-工具包(JVM分析工具),学习笔记,Java,学习,笔记,jvm,分析工具,jvm分析
更多资料文章来源地址https://www.toymoban.com/news/detail-648030.html

到了这里,关于学习笔记-JVM-工具包(JVM分析工具)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 开源机器学习工具包——PyTorch高级API简介

    作者:禅与计算机程序设计艺术 随着深度学习的不断发展,近年来在图像、文本、音频等领域取得重大突破,无论是识别率还是模型大小都有了明显的提升。因此,基于深度学习技术的应用在各行各业都得到广泛的应用。但这些模型往往较为复杂,使用起来也比较繁琐。Te

    2024年02月04日
    浏览(55)
  • 以太坊怎么扫块?推荐你一个Java工具包

    Magician-web3,开发语言是 java ,底层依赖了 Web3J , 废话不多说,直接上示例 监听器 可以创建多个,根据你的需求 分别设置监听条件

    2024年02月16日
    浏览(53)
  • 有了这个工具包,用Java调用智能合约更加简便

    Magician-ContractsTools是一个用于调用智能合约的工具包,你可以非常容易地在Java程序中调用智能合约进行查询和写入操作。 有三个内置的标准合约模板,分别是ERC20、ERC721和ERC1155,如果你需要调用这三个合约中的标准函数,可以帮助你非常快速地完成工作。除了内置的合同模板

    2024年02月11日
    浏览(50)
  • Java扫描区块链的工具包|Java扫块|监听token转账

    Magician-Scanning是一个用Java开发的扫描区块链的工具包,当我们在程序中需要一些功能时,它可以派上用场,比如说。 当一个地址收到ETH时,程序中的一个方法会被自动触发,这个交易会被传入该方法。 当一个合约的某个功能被调用时(比如 ERC20 转账),它会自动触发程序中

    2024年01月17日
    浏览(50)
  • 基因表达差异分析R工具包DESeq2的详细使用方法和使用案例

    DESeq2是一种常用的差异表达基因分析工具,可用于RNA-seq数据的差异表达分析。下面是DESeq2的详细使用步骤和全部脚本示例。 文章参考 Moderated estimation of fold change and dispersion for RNA-seq data with DESeq2 | Genome Biology | Full Text (biomedcentral.com) bioconda源对工具包的介绍: Bioconductor - DES

    2024年04月15日
    浏览(53)
  • Java+GeoTools(开源的Java GIS工具包)快速入门-实现读取shp文件并显示

    GeoTools 是一个开源的 Java GIS 工具包,可利用它来开发符合标准的地理信息系统。 GeoTools 提供了 OGC (Open Geospatial Consortium) 规范的一个实现来作为他们的开发。 官网地址: GeoTools The Open Source Java GIS Toolkit — GeoTools 参考其quick start教程,实现集成到maven项目中并运行示例代码。

    2024年02月08日
    浏览(72)
  • JAVA深化篇_26——Apache commons-io工具包的使用

    Apache基金会介绍 Apache软件基金会(也就是Apache Software Foundation,简称为ASF),是专门为支持开源软件项目而办的一个非盈利性组织。在它所支持的Apache项目与子项目中,所发行的软件产品都遵循Apache许可证(Apache License)。 官方网址为:www.apache.org 。 很多著名的Java开源项目

    2024年02月06日
    浏览(61)
  • Java智能合约工具包|Java调用智能合约|Java调用ERC20、ERC721、ERC1155合约

    Magician-ContractsTools是一个用于调用智能合约的工具包,你可以非常容易地在Java程序中调用智能合约进行查询和写入操作。 有三个内置的标准合约模板,分别是ERC20、ERC721和ERC1155,如果你需要调用这三个合约中的标准函数,可以帮助你非常快速地完成工作。除了内置的合同模板

    2024年02月11日
    浏览(54)
  • 跨平台的开源Java生成PPT文件工具包,PPTShowV1.3更新啦

    项目官网:https://pptshow.cc/ 参考文档:https://pptshow.cc/book/(GitPage制作,打不开请科学冲浪) 开源地址:https://github.com/qrpcode/pptshow(有帮助记得点star呀~) 国内镜像:中文版本(Gitee)     Github镜像(Gitcode) PPTShow是一个开源的Java生成PPT文档工具包,支持2010版PPTX新特性。

    2024年02月09日
    浏览(47)
  • 生物系统学中的进化树构建和分析R工具包V.PhyloMaker2的介绍和详细使用

    V.PhyloMaker2是一个R语言的工具包,专门用于构建和分析生物系统学中的进化树(也称为系统发育树或phylogenetic tree)。以下是对V.PhyloMaker2的一些基本介绍和使用说明: 论文介绍:V.PhyloMaker2: An updated and enlarged R package that can generate very large phylogenies for vascular plants - ScienceDirect  

    2024年02月04日
    浏览(124)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包