您的位置:

jstatgc占用cpu,jstat gc

jstatgc占用cpu,jstat gc

更新:

本文目录一览:

记一次线上机器CPU飙高的排查过程

        公司如今把小贷机器都整理回收了,访问量不大,基本都是用户来查看账户进行还款操作。

        现在情况是,我们把很多服务都放在了一台服务器上,那天线上环境改了auth的salt,本地这边是写死的,自动上线已经关闭了通道,没辙,手动替包手动上线,结果没多久运维就喊了,表示cpu飙高到300%。

        难得的机会,先用top找出cpu占用最多进程

如果想细看进程信息可以使用ll proc

其实运行完这里的时候,我比较吃惊的是,真正占CPU的并不是部署的几个服务,而是resin容器本身,飚到了99%,从这个角度来讲,其实大部分性能问题都是垃圾回收的锅。

然后利用ps查看到的进程pid找cpu最高线程

然后拿着线程tid在jstack找,结果在里面找不到,然后上网查JAVA线程无法在jstack里找到的原因

以上大概意思是没找到线程的跟踪栈有三种情况,就是线程启动前的预启动,以及线程退出后的cleanup,第三种就是,利用JVM TI agent运行的线程,这个线程是用来跑本地code的。

******这里面都提到了JVM TI技术,这个技术主要是用来提供虚拟机调用本地方法的接口,可以获取jvm运行情况和提供本地方法的后门一样的接口工具,一些调试和诊断工具都是基于JVM TI来实现的,很多JVM都有自己的TI实现。

当然,这个Stack Over Flow的答案针对的Java线程,我所知道的是,如果导致我们CPU飙高的并不是java线程,那么jstack -F就打不出来。

而这个jstack -m模式,在官方文档里是说,可以打印出所有Java线程和native frames的所有线程。其实到这里是不是隐隐感觉到什么了~~没错,最后真的是垃圾回收的锅。

然后jdk8利用jstack -m找到了,发现里面使用的方法是CMS垃圾回收器的方法

讲真,平时只负责上下线,JVM配置只要不出问题很少留意,这个年代了,还在使用CMS吗?嗯,jmap看了下,是CMS。而占用大多CPU也是CMS的特性之一:最小化GC中断,付出的代价便是高CPU负荷。

既然定位到了垃圾回收,那就接着排查垃圾回收吧,pid是18637

就去jstat -gc 18637 5000

jstat -gcold 18637

jstat -gcoldcapacity 18637

发现full gc非常频繁(每五秒输出,发现触发fullGC13次)

(复盘这次的排查问题,发现图片保存少之又少。。)

如此频繁,顺带gccause一下看看最近一次回收的原因

结果长这样

从这个结果来看最近一次是Metadata的GC,而触发原因是因为达到了阈值。再细看当前元空间使用率已经接近98%。

到这里不能等了,找运维拿来了jvm参数,有三个参数很亮眼

老年代的配置属于默认配置,占整个堆内存的2/3,CMS回收要达到80%才会触发,我们还没有达到这个值。

那么根据图1中的显示,metaspace我们已经达到了阈值。

这种情况产生也没毛病,想想一台机器部署了5个web服务和5个微服务的场景吧,虽然没什么人访问,但加载的class信息也足够多了。

主要就是metadata的配置,而有关metadata的配置并没有oracle的官方指导,官方指导上的意思是说metaspace的配置,主要是避免首次启动时对加载的类信息做回收,取决于应用本身,够用就行了,不要太频繁触发full gc就好

其实调大这metaspace的配置能够大概解决问题,但是最终我选择了切换为G1垃圾回收。

官方文档是这样写的

        首先戳我的点的主要原因是g1最终的目的是要取代cms垃圾回收器,它的回收范围是整个堆,紧跟潮流总不会错的。其次g1取代cms的情况官方也建议了以下几点:

1. 一个是要管理的堆内存大于6g

2. 一个是服务已使用的堆内存超过了50%

3. 一个是对象分配率过高或对象从新生代晋升到老年代速率过快(这里我查了一下资料,意思是对象分配率过高的话其实会导致Minor GC频繁,而这种情况会使对象更快地晋升到老年代,而老年代如果过快地被填充,又会触发FullGC。从设计角度来讲,之所以分代回收,是为了应对对象存活时间而使用不同的回收策略,老年代可不是为了频繁回收而产生的)

4. 垃圾回收导致服务中断时长超过0.5-1s。

这种时候官方就建议把cms换成g1了。

        最终cpu骤降,从99%降至一般运行状态下的2%左右。好了。就这样吧,虽然不希望线上出现这种问题,但一旦出问题了,搞一遍还蛮带感的。期待下一次的摸排:DDDDD

后记:

        最近在复盘这次垃圾回收,因为这次jvm排查的经历让我对垃圾回收机制和分代回收这一块加深了印象。复盘的时候发现自己思考地还欠缺深入。这次的问题有两个地方值得深思,一个是为什么metaspace会超?如果正常进行GC,为何会超出阈值?其次是没有调大metaspace的前提下,换成G1为什么就没有再频繁FullGC过?

        为什么metaspace会超,我经过比对当时留下CMS的jstat数据和G1当前的数据,发现新生代CMS划分区域非常大,是现在G1的十倍。G1是不建议设定新老年代比例的,这样它就可以动态调整新老年代比例,达到最优实践。首先说明metaspace是存储类描述信息的,当堆上分配了对象,就会关联到metaspace里面的类信息,如果堆上的对象不回收,那么metaspace里面的类信息也不会回收。

        在配置cms时,我们会设置新生代老年代比例,新生代空间是固定的,如果新生代的空间比较大,回收间隔时间长,那就会导致metaspace里的class信息无法被释放,最终导致未进行youngGC而率先因为metaspace超了跑了FullGC。但G1的新生代空间是根据使用情况动态分配的,它的算法会去回收最有回收价值的region。

        就这次修改参数而言,使用G1比CMS时间短很多,就已经执行了717次youngGC,而CMS用了那么久,才52次,侧面也能佐证这个猜测的正确性,解释了为何在相同metaspace的配置下,G1没有产生频繁FullGC的原因:新生代对象回收加快,metaspace空间得到了尽快释放,没有达到阈值,于是不会触发FullGC。

参考文献:

*

*

*

*

*

jvm 性能调优工具之 jstat 命令详解

Jstat名称:Java Virtual Machine statistics monitoring tool

功能描述:

Jstat是JDK自带的一个轻量级小工具。它位于java的bin目录下,主要利用JVM内建的指令对Java应用程序的资源和性能进行实时的命令行的监控,包括了对Heap size和垃圾回收状况的监控。

命令用法:jstat [-命令选项] [vmid] [间隔时间/毫秒] [查询次数]

注意:使用的jdk版本是jdk8。

C:\Users\Administratorjstat -helpUsage: jstat -help|-options jstat -option [-t] [-hlines] vmid [interval [count]] Definitions: option An option reported by the -options option vmid Virtual Machine Identifier. A vmid takes the following form: lvmid[@hostname[:port]] Where lvmid is the local vm identifier for the target Java virtual machine, typically a process id; hostname is the name of the host running the target Java virtual machine; and port is the port number for the rmiregistry on the target host. See the jvmstat documentation for a more complete description of the Virtual Machine Identifier. lines Number of samples between header lines. interval Sampling interval. The following forms are allowed: n["ms"|"s"] Where n is an integer and the suffix specifies the units as milliseconds("ms") or seconds("s"). The default units are "ms". count Number of samples to take before terminating. -Jflag Pass flag directly to the runtime system.

option:参数选项

-t:可以在打印的列加上Timestamp列,用于显示系统运行的时间

-h:可以在周期性数据输出的时候,指定输出多少行以后输出一次表头

vmid:Virtual Machine ID( 进程的 pid)

interval:执行每次的间隔时间,单位为毫秒

count:用于指定输出多少次记录,缺省则会一直打印

option 可以从下面参数中选择

jstat -options

-class 用于查看类加载情况的统计

-compiler 用于查看HotSpot中即时编译器编译情况的统计

-gc 用于查看JVM中堆的垃圾收集情况的统计

-gccapacity 用于查看新生代、老生代及持久代的存储容量情况

-gcmetacapacity 显示metaspace的大小

-gcnew 用于查看新生代垃圾收集的情况

-gcnewcapacity 用于查看新生代存储容量的情况

-gcold 用于查看老生代及持久代垃圾收集的情况

-gcoldcapacity 用于查看老生代的容量

-gcutil 显示垃圾收集信息

-gccause 显示垃圾回收的相关信息(通-gcutil),同时显示最后一次仅当前正在发生的垃圾收集的原因

-printcompilation 输出JIT编译的方法信息

示例:

1.-class 类加载统计

[root@hadoop ~]# jps #先通过jps获取到java进程号(这里是一个zookeeper进程)3346 QuorumPeerMain7063 Jps[root@hadoop ~]# jstat -class 3346 #统计JVM中加载的类的数量与sizeLoaded Bytes Unloaded Bytes Time 1527 2842.7 0 0.0 1.02

Loaded:加载类的数量

Bytes:加载类的size,单位为Byte

Unloaded:卸载类的数目

Bytes:卸载类的size,单位为Byte

Time:加载与卸载类花费的时间

2.-compiler 编译统计

[root@hadoop ~]# jstat -compiler 3346 #用于查看HotSpot中即时编译器编译情况的统计Compiled Failed Invalid Time FailedType FailedMethod 404 0 0 0.19 0

Compiled:编译任务执行数量

Failed:编译任务执行失败数量

Invalid:编译任务执行失效数量

Time:编译任务消耗时间

FailedType:最后一个编译失败任务的类型

FailedMethod:最后一个编译失败任务所在的类及方法

3.-gc 垃圾回收统计

[root@hadoop ~]# jstat -gc 3346 #用于查看JVM中堆的垃圾收集情况的统计 S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT 128.0 128.0 0.0 128.0 1024.0 919.8 15104.0 2042.4 8448.0 8130.4 1024.0 996.0 7 0.019 0 0.000 0.019

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)

4.-gccapacity 堆内存统计

[root@hadoop ~]# jstat -gccapacity 3346 #用于查看新生代、老生代及持久代的存储容量情况 NGCMN NGCMX NGC S0C S1C EC OGCMN OGCMX OGC OC MCMN MCMX MC CCSMN CCSMX CCSC YGC FGC 1280.0 83264.0 1280.0 128.0 128.0 1024.0 15104.0 166592.0 15104.0 15104.0 0.0 1056768.0 8448.0 0.0 1048576.0 1024.0 7 0[root@hadoop ~]# jstat -gccapacity -h5 3346 1000 #-h5:每5行显示一次表头 1000:每1秒钟显示一次,单位为毫秒 NGCMN NGCMX NGC S0C S1C EC OGCMN OGCMX OGC OC MCMN MCMX MC CCSMN CCSMX CCSC YGC FGC 1280.0 83264.0 1280.0 128.0 128.0 1024.0 15104.0 166592.0 15104.0 15104.0 0.0 1056768.0 8448.0 0.0 1048576.0 1024.0 7 0 1280.0 83264.0 1280.0 128.0 128.0 1024.0 15104.0 166592.0 15104.0 15104.0 0.0 1056768.0 8448.0 0.0 1048576.0 1024.0 7 0 1280.0 83264.0 1280.0 128.0 128.0 1024.0 15104.0 166592.0 15104.0 15104.0 0.0 1056768.0 8448.0 0.0 1048576.0 1024.0 7 0 1280.0 83264.0 1280.0 128.0 128.0 1024.0 15104.0 166592.0 15104.0 15104.0 0.0 1056768.0 8448.0 0.0 1048576.0 1024.0 7 0 1280.0 83264.0 1280.0 128.0 128.0 1024.0 15104.0 166592.0 15104.0 15104.0 0.0 1056768.0 8448.0 0.0 1048576.0 1024.0 7 0 NGCMN NGCMX NGC S0C S1C EC OGCMN OGCMX OGC OC MCMN MCMX MC CCSMN CCSMX CCSC YGC FGC 1280.0 83264.0 1280.0 128.0 128.0 1024.0 15104.0 166592.0 15104.0 15104.0 0.0 1056768.0 8448.0 0.0 1048576.0 1024.0 7 0 1280.0 83264.0 1280.0 128.0 128.0 1024.0 15104.0 166592.0 15104.0 15104.0 0.0 1056768.0 8448.0 0.0 1048576.0 1024.0 7 0 1280.0 83264.0 1280.0 128.0 128.0 1024.0 15104.0 166592.0 15104.0 15104.0 0.0 1056768.0 8448.0 0.0 1048576.0 1024.0 7 0 1280.0 83264.0 1280.0 128.0 128.0 1024.0 15104.0 166592.0 15104.0 15104.0 0.0 1056768.0 8448.0 0.0 1048576.0 1024.0 7 0

NGCMN:年轻代(young)中初始化(最小)的大小(字节)

NGCMX:年轻代(young)的最大容量 (字节)

NGC:年轻代(young)中当前的容量 (字节)

S0C:年轻代中第一个survivor(幸存区)的容量 (字节)

S1C:年轻代中第二个survivor(幸存区)的容量 (字节)

EC:年轻代中Eden(伊甸园)的容量 (字节)

OGCMN:old代中初始化(最小)的大小 (字节)

OGCMX:old代的最大容量(字节)

OGC:old代当前新生成的容量 (字节)

OC:Old代的容量 (字节)

MCMN:metaspace(元空间)中初始化(最小)的大小 (字节)

MCMX:metaspace(元空间)的最大容量 (字节)

MC:metaspace(元空间)当前新生成的容量 (字节)

CCSMN:最小压缩类空间大小

CCSMX:最大压缩类空间大小

CCSC:当前压缩类空间大小

YGC:从应用程序启动到采样时年轻代中gc次数

FGC:从应用程序启动到采样时old代(全gc)gc次数

5.-gcmetacapacity 元数据空间统计

[root@hadoop ~]# jstat -gcmetacapacity 3346 #显示元数据空间的大小MCMN MCMX MC CCSMN CCSMX CCSC YGC FGC FGCT GCT0.0 1056768.0 8448.0 0.0 1048576.0 1024.0 8 0 0.000 0.020

MCMN:最小元数据容量

MCMX:最大元数据容量

MC:当前元数据空间大小

CCSMN:最小压缩类空间大小

CCSMX:最大压缩类空间大小

CCSC:当前压缩类空间大小

YGC:从应用程序启动到采样时年轻代中gc次数

FGC:从应用程序启动到采样时old代(全gc)gc次数

FGCT:从应用程序启动到采样时old代(全gc)gc所用时间(s)

GCT:从应用程序启动到采样时gc用的总时间(s)

6.-gcnew 新生代垃圾回收统计

[root@hadoop ~]# jstat -gcnew 3346 #用于查看新生代垃圾收集的情况S0C S1C S0U S1U TT MTT DSS EC EU YGC YGCT128.0 128.0 67.8 0.0 1 15 64.0 1024.0 362.2 8 0.020

S0C:年轻代中第一个survivor(幸存区)的容量 (字节)

S1C:年轻代中第二个survivor(幸存区)的容量 (字节)

S0U:年轻代中第一个survivor(幸存区)目前已使用空间 (字节)

S1U:年轻代中第二个survivor(幸存区)目前已使用空间 (字节)

TT:持有次数限制

MTT:最大持有次数限制

DSS:期望的幸存区大小

EC:年轻代中Eden(伊甸园)的容量 (字节)

EU:年轻代中Eden(伊甸园)目前已使用空间 (字节)

YGC:从应用程序启动到采样时年轻代中gc次数

YGCT:从应用程序启动到采样时年轻代中gc所用时间(s)

7.-gcnewcapacity 新生代内存统计

[root@hadoop ~]# jstat -gcnewcapacity 3346 #用于查看新生代存储容量的情况NGCMN NGCMX NGC S0CMX S0C S1CMX S1C ECMX EC YGC FGC1280.0 83264.0 1280.0 8320.0 128.0 8320.0 128.0 66624.0 1024.0 8 0

NGCMN:年轻代(young)中初始化(最小)的大小(字节)

NGCMX:年轻代(young)的最大容量 (字节)

NGC:年轻代(young)中当前的容量 (字节)

S0CMX:年轻代中第一个survivor(幸存区)的最大容量 (字节)

S0C:年轻代中第一个survivor(幸存区)的容量 (字节)

S1CMX:年轻代中第二个survivor(幸存区)的最大容量 (字节)

S1C:年轻代中第二个survivor(幸存区)的容量 (字节)

ECMX:年轻代中Eden(伊甸园)的最大容量 (字节)

EC:年轻代中Eden(伊甸园)的容量 (字节)

YGC:从应用程序启动到采样时年轻代中gc次数

FGC:从应用程序启动到采样时old代(全gc)gc次数

8.-gcold 老年代垃圾回收统计

[root@hadoop ~]# jstat -gcold 3346 #用于查看老年代及持久代垃圾收集的情况MC MU CCSC CCSU OC OU YGC FGC FGCT GCT8448.0 8227.5 1024.0 1003.7 15104.0 2102.2 8 0 0.000 0.020 

MC:metaspace(元空间)的容量 (字节)

MU:metaspace(元空间)目前已使用空间 (字节)

CCSC:压缩类空间大小

CCSU:压缩类空间使用大小

OC:Old代的容量 (字节)

OU:Old代目前已使用空间 (字节)

YGC:从应用程序启动到采样时年轻代中gc次数

FGC:从应用程序启动到采样时old代(全gc)gc次数

FGCT:从应用程序启动到采样时old代(全gc)gc所用时间(s)

GCT:从应用程序启动到采样时gc用的总时间(s)

9.-gcoldcapacity 老年代内存统计

[root@hadoop ~]# jstat -gcoldcapacity 3346 #用于查看老年代的容量OGCMN OGCMX OGC OC YGC FGC FGCT GCT15104.0 166592.0 15104.0 15104.0 8 0 0.000 0.020

OGCMN:old代中初始化(最小)的大小 (字节)OGCMX:old代的最大容量(字节)OGC:old代当前新生成的容量 (字节)OC:Old代的容量 (字节)YGC:从应用程序启动到采样时年轻代中gc次数FGC:从应用程序启动到采样时old代(全gc)gc次数FGCT:从应用程序启动到采样时old代(全gc)gc所用时间(s)GCT:从应用程序启动到采样时gc用的总时间(s) 在此我向大家推荐一个架构学习交流圈。交流学习指导伪鑫:1253431195(里面有大量的面试题及答案)里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化、分布式架构等这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多

10.-gcutil 垃圾回收统计

[root@hadoop ~]# jstat -gcutil 3346 #显示垃圾收集信息S0 S1 E O M CCS YGC YGCT FGC FGCT GCT52.97 0.00 42.10 13.92 97.39 98.02 8 0.020 0 0.000 0.020 

S0:年轻代中第一个survivor(幸存区)已使用的占当前容量百分比

S1:年轻代中第二个survivor(幸存区)已使用的占当前容量百分比

E:年轻代中Eden(伊甸园)已使用的占当前容量百分比

O:old代已使用的占当前容量百分比

M:元数据区已使用的占当前容量百分比

CCS:压缩类空间已使用的占当前容量百分比

YGC :从应用程序启动到采样时年轻代中gc次数

YGCT :从应用程序启动到采样时年轻代中gc所用时间(s)

FGC :从应用程序启动到采样时old代(全gc)gc次数

FGCT :从应用程序启动到采样时old代(全gc)gc所用时间(s)

GCT:从应用程序启动到采样时gc用的总时间(s)

11.-gccause

[root@hadoop ~]# jstat -gccause 3346 #显示垃圾回收的相关信息(通-gcutil),同时显示最后一次或当前正在发生的垃圾回收的诱因S0 S1 E O M CCS YGC YGCT FGC FGCT GCT LGCC GCC52.97 0.00 46.09 13.92 97.39 98.02 8 0.020 0 0.000 0.020 Allocation Failure No GC

LGCC:最后一次GC原因

GCC:当前GC原因(No GC 为当前没有执行GC)

12.-printcompilation JVM编译方法统计

[root@hadoop ~]# jstat -printcompilation 3346 #输出JIT编译的方法信息Compiled Size Type Method421 60 1 sun/nio/ch/Util$2 clear

Compiled:编译任务的数目

Size:方法生成的字节码的大小

Type:编译类型

Method:类名和方法名用来标识编译的方法。类名使用/做为一个命名空间分隔符。方法名是给定类中的方法。上述格式是由-XX:+PrintComplation选项进行设置的

远程监控

与jps一样,jstat也支持远程监控,同样也需要开启安全授权,方法参照jps。

C:\Users\Administratorjps 192.168.146.1283346 QuorumPeerMain3475 JstatdC:\Users\Administratorjstat -gcutil 3346@192.168.146.128 S0 S1 E O M CCS YGC YGCT FGC FGCT GCT 52.97 0.00 65.15 13.92 97.39 98.02 8 0.020 0 0.000 0.020

cpu飙升怎么排查

一、引子

对于互联网公司,线上CPU飙升的问题很常见(例如某个活动开始,流量突然飙升时),按照本文的步骤排查,基本1分钟即可搞定!特此整理排查方法一篇,供大家参考讨论提高。

二、问题复现

线上系统突然运行缓慢,CPU飙升,甚至到100%,以及Full GC次数过多,接着就是各种报警:例如接口超时报警等。此时急需快速线上排查问题。

三、问题排查

不管什么问题,既然是CPU飙升,肯定是查一下耗CPU的线程,然后看看GC。

3.1 核心排查步骤

1.执行“top”命令:查看所有进程占系统CPU的排序。极大可能排第一个的就是咱们的java进程(COMMAND列)。PID那一列就是进程号。

2.执行“top -Hp 进程号”命令:查看java进程下的所有线程占CPU的情况。

3.执行“printf "%x\n 10"命令 :后续查看线程堆栈信息展示的都是十六进制,为了找到咱们的线程堆栈信息,咱们需要把线程号转成16进制。例如,printf "%x\n 10-》打印:a,那么在jstack中线程号就是0xa.

4.执行 “jstack 进程号 | grep 线程ID” 查找某进程下-》线程ID(jstack堆栈信息中的nid)=0xa的线程堆栈信息。如果“"VM Thread" os_prio=0 tid=0x00007f871806e000 nid=0xa runnable”,第一个双引号圈起来的就是线程名,如果是“VM Thread”这就是虚拟机GC回收线程了

5.执行“jstat -gcutil 进程号 统计间隔毫秒 统计次数(缺省代表一致统计)”,查看某进程GC持续变化情况,如果发现返回中FGC很大且一直增大-》确认Full GC! 也可以使用“jmap -heap 进程ID”查看一下进程的堆内从是不是要溢出了,特别是老年代内从使用情况一般是达到阈值(具体看垃圾回收器和启动时配置的阈值)就会进程Full GC。

6.执行“jmap -dump:format=b,file=filename 进程ID”,导出某进程下内存heap输出到文件中。可以通过eclipse的mat工具查看内存中有哪些对象比较多。

3.2 原因分析

1.内存消耗过大,导致Full GC次数过多

执行步骤1-5:

多个线程的CPU都超过了100%,通过jstack命令可以看到这些线程主要是垃圾回收线程-》上一节步骤2

通过jstat命令监控GC情况,可以看到Full GC次数非常多,并且次数在不断增加。--》上一节步骤5

确定是Full GC,接下来找到具体原因:

生成大量的对象,导致内存溢出-》执行步骤6,查看具体内存对象占用情况。

内存占用不高,但是Full GC次数还是比较多,此时可能是代码中手动调用 System.gc()导致GC次数过多,这可以通过添加 -XX:+DisableExplicitGC来禁用JVM对显示GC的响应。

2.代码中有大量消耗CPU的操作,导致CPU过高,系统运行缓慢;

执行步骤1-4:在步骤4jstack,可直接定位到代码行。例如某些复杂算法,甚至算法BUG,无限循环递归等等。

3.由于锁使用不当,导致死锁。

执行步骤1-4:如果有死锁,会直接提示。关键字:deadlock.步骤四,会打印出业务死锁的位置。

造成死锁的原因:最典型的就是2个线程互相等待对方持有的锁。

4.随机出现大量线程访问接口缓慢。

代码某个位置有阻塞性的操作,导致该功能调用整体比较耗时,但出现是比较随机的;平时消耗的CPU不多,而且占用的内存也不高。

思路:

首先找到该接口,通过压测工具不断加大访问力度,大量线程将阻塞于该阻塞点。

使用jstat命令会影响java进程吗

使用jstat命令会影响java进程

JDK自带VM分析工具jps,jstat,jmap,jconsole

关键字: jdk自带vm分析工具jps,jstat,jmap,jconsole

一、概述

SUN 的JDK中的几个工具,非常好用。秉承着有免费,不用商用的原则。以下简单介绍一下这几种工具。(注:本文章下的所有工具都存在JDK5.0以上版本的工具集里,同javac一样,不须特意安装) 。

我一共找到以下四个工具:重点看看jconsole和jmap。

jps

:与unix上的ps类似,用来显示本地的java进程,可以查看本地运行着几个java程序,并显示他们的进程号。

jstat

:一个极强的监视VM内存工具。可以用来监视VM内存内的各种堆和非堆的大小及其内存使用量。

jmap

:打印出某个java进程(使用pid)内存内的所有‘对象’的情况(如:产生那些对象,及其数量)。

jconsole

:一个java GUI监视工具,可以以图表化的形式显示各种数据。并可通过远程连接监视远程的服务器VM。

二、 使用介绍:

1、jps :我想很多人都是用过unix系统里的ps命令,这个命令主要是用来显示当前系统的进程情况,有哪些进程,及其 id。 jps 也是一样,它的作用是显示当前系统的java进程情况,及其id号。我们可以通过它来查看我们到底启动了几个java进程(因为每一个java程序都会独占一个java虚拟机实例),和他们的进程号(为下面几个程序做准备),并可通过opt来查看这些进程的详细启动参数。

使用方法:在当前命令行下打 jps(需要JAVA_HOME,没有的话,到改程序的目录下打) 。

可惜没有linux下的ps好用,名称不好用。但是在第四个工具jconsole的界面里面会有具体JAR包的名称。

2、jstat :对VM内存使用量进行监控。

jstat工具特别强大,有众多的可选项,详细查看堆内各个部分的使用量,以及加载类的数量。使用时,需加上查看进程的进程id,和所选参数。以下详细介绍各个参数的意义。

jstat -class pid:显示加载class的数量,及所占空间等信息。

jstat -compiler pid:显示VM实时编译的数量等信息。

jstat -gc pid:可以显示gc的信息,查看gc的次数,及时间。其中最后五项,分别是young gc的次数,young gc的时间,full gc的次数,full gc的时间,gc的总时间。

jstat -gccapacity:可以显示,VM内存中三代(young,old,perm)对象的使用和占用大小,如:PGCMN显示的是最小perm的内存使用量,PGCMX显示的是perm的内存最大使用量,PGC是当前新生成的perm内存占用量,PC是但前perm内存占用量。其他的可以根据这个类推, OC是old内纯的占用量。

jstat -gcnew pid:new对象的信息。

jstat -gcnewcapacity pid:new对象的信息及其占用量。

jstat -gcold pid:old对象的信息。

jstat -gcoldcapacity pid:old对象的信息及其占用量。

jstat -gcpermcapacity pid: perm对象的信息及其占用量。

jstat -util pid:统计gc信息统计。

jstat -printcompilation pid:当前VM执行的信息。

除了以上一个参数外,还可以同时加上 两个数字,如:jstat -printcompilation 3024 250 6是每250毫秒打印一次,一共打印6次,还可以加上-h3每三行显示一下标题。

3、jmap 是一个可以输出所有内存中对象的工具,甚至可以将VM 中的heap,以二进制输出成文本。使用方法 jmap -histo pid。如果连用 SHELL jmap -histo pida.log可以将其保存到文本中去(windows下也可以使用),在一段时间后,使用文本对比工具,可以对比出GC回收了哪些对象。 jmap -dump:format=b,file=f1 3024可以将3024进程的内存heap输出出来到f1文件里。

4、jconsole 是一个用java写的GUI程序,用来监控VM,并可监控远程的VM,非常易用,而且功能非常强。由于是GUI程序,这里就不详细介绍了,不会的地方可以参考SUN的官方文档。

使用方法:命令行里打 jconsole,选则进程就可以了。

友好提示:windows查看进程号,由于任务管理器默认的情况下是不显示进程id号的,所以可以通过如下方法加上。ctrl+alt+del打开任务管理器,选择‘进程’选项卡,点‘查看’-''选择列''-加上''PID'',就可以了。当然还有其他很好的选项。

Linux使用jstat命令查看jvm的GC情况

Linux 使用jstat命令查看jvm的GC情况

命令格式

jstat命令命令格式:

jstat [Options] vmid[interval] [count]

参数说明:

Options,选项,我们一般使用 -gcutil 查看gc情况

vmid

,VM的进程号,即当前运行的java进程号

interval

,间隔时间,单位为秒或者毫秒

count

,打印次数,如果缺省则打印无数次

示例说明

示例

通常运行命令如下:

jstat -gc 12538 5000

即会每5秒一次显示进程号为12538的java进成的GC情况,

显示内容如下图:

结果说明

   S0C:年轻代中第一个survivor(幸存区)的容量 (字节)

S1C

:年轻代中第二个survivor(幸存区)的容量 (字节)

S0U

:年轻代中第一个survivor(幸存区)目前已使用空间 (字节)

S1U

:年轻代中第二个survivor(幸存区)目前已使用空间 (字节)

EC

:年轻代中Eden(伊甸园)的容量 (字节)

EU

:年轻代中Eden(伊甸园)目前已使用空间 (字节)

OC

:Old代的容量 (字节)

OU

:Old代目前已使用空间 (字节)

PC

:Perm(持久代)的容量 (字节)

PU

:Perm(持久代)目前已使用空间 (字节)

YGC

:从应用程序启动到采样时年轻代中gc次数

YGCT

:从应用程序启动到采样时年轻代中gc所用时间(s)

FGC

:从应用程序启动到采样时old代(全gc)gc次数

FGCT

:从应用程序启动到采样时old代(全gc)gc所用时间(s)

GCT

:从应用程序启动到采样时gc用的总时间(s)

NGCMN

:年轻代(young)中初始化(最小)的大小 (字节)

NGCMX

:年轻代(young)的最大容量 (字节)

NGC

:年轻代(young)中当前的容量 (字节)

OGCMN

:old代中初始化(最小)的大小 (字节)

OGCMX

:old代的最大容量 (字节)

OGC

:old代当前新生成的容量 (字节)

PGCMN

:perm代中初始化(最小)的大小 (字节)

PGCMX

:perm代的最大容量 (字节)

PGC

:perm代当前新生成的容量 (字节)

S0

:年轻代中第一个survivor(幸存区)已使用的占当前容量百分比

S1

:年轻代中第二个survivor(幸存区)已使用的占当前容量百分比

E

:年轻代中Eden(伊甸园)已使用的占当前容量百分比

O

:old代已使用的占当前容量百分比

P

:perm代已使用的占当前容量百分比

S0CMX

:年轻代中第一个survivor(幸存区)的最大容量 (字节)

S1CMX

:年轻代中第二个survivor(幸存区)的最大容量 (字节)

ECMX

:年轻代中Eden(伊甸园)的最大容量 (字节)

DSS

:当前需要survivor(幸存区)的容量 (字节)(Eden区已满)

TT

: 持有次数限制

MTT

: 最大持有次数限制