产品如何做网站地图/广州网站优化价格
如何应对线上服务出现full gc
目录
top和ps
dump 一下内存数据
jhat命令
OQL
jmap命令
jstack命令
jstat命令
top和ps
用top 命令查看对应java的pid(这边是62147),也可以用ps查线对应服务进程的pid
ps -ef | grep java | grep ‘服务名’
dump 一下内存数据
保存、恢复:保存好相应的错误数据,再对机器一一进行重启,事后再 进行分析处理,先恢复线上服务。
然后进入java的bin目录,输入下面指令:
// 使用hprof二进制形式,输出jvm的heap内容到文件
jmap -dump:format=b,file=/usr/local/project.hprof 62147
jhat命令
JDK自带的堆分析工具--jhat命令
使用jhat命令 可以分析Java 应用程序的堆快照内容。(jhat命令在JDK9、JDK10已经被删除,建议使用VisualVm代替)。
jhat c:\project.hprof
在分析完成后,使用HTTP服务器展示其分析结果。在浏览器中访问:http://localhost:7000
在默认页中,jhat服务器显示了所有的非平台类信息。
点击链接,可以查看选中类的超类(SuperClass)、类加载器(ClassLoader)及该类的实例(instance)等信息。
OQL
该页面底部,存在其他的查询功能,如OQL查询界面。
OQL对堆快照进行查询。例如,查询出当前Java程序中所有java.io.File对象的路径,如下所示:
select file.path.value.toString() from java.io.File file
筛选长度大于等于100的字符串
select s from java.lang.String s where s.value.length >= 100
筛选长度大于等于256的int数组
select a from int[] a where a.length >= 256
筛选出以 "ab" 开头的字符串,select子句用了JSON语法,where 子句使用正则表达式。(jhat貌似不支持正则表达式,visual VM支持)
select {instance:s, content:s.toString()} from java.lang.String s where /^ab.*$/(s.toString())
使用instanceof 关键字选取所有的ClassLoader,包括子类:
select cl from instanceof java.lang.ClassLoader cl
内置heap对象
heap对象是内置对象,主要方法有:
forEachClass(callback): callback为JavaScript函数,执行一个回调操作
findClass():查找指定名称的类对象
classes():所有的类集合
objects(clazz,[includeSubtypes],[filter]):所有的类集合,其中clazz指定类名称,includeSubtypes指定是否选出子类, filter指定筛选规则
livepaths():返回指定对象的存活路径
roots(): 返回这个堆的根对象
查找Vector类
select heap.findClass("java.util.Vector")
查找Vector类的所有父类:
select heap.findClass("java.util.Vector").superclasses()
对象函数
内置了对象的函数,常用的有:classof()、objectid()、reachables()、referrers()、referees()、sizeof()、resizeof()、toHtml()函数
集合/统计函数
方便对结果集进行处理或者统计操作,常用的函数有:
contains()、count()、filter()、length()、map()、max()、min()、sort()、top()、sum()、unique()等
jmap命令
// 打印heap的概要信息,GC使用的算法,heap的配置及wise heap的使用情况.
jmap -heap 62147
内容如下:
Attaching to process ID 62147, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.202-b08using parallel threads in the new generation.
using thread-local object allocation.
Concurrent Mark-Sweep GCHeap Configuration:MinHeapFreeRatio = 40MaxHeapFreeRatio = 70MaxHeapSize = 1073741824 (1024.0MB)NewSize = 134217728 (128.0MB)MaxNewSize = 134217728 (128.0MB)OldSize = 939524096 (896.0MB)NewRatio = 2SurvivorRatio = 8MetaspaceSize = 268435456 (256.0MB)CompressedClassSpaceSize = 260046848 (248.0MB)MaxMetaspaceSize = 268435456 (256.0MB)G1HeapRegionSize = 0 (0.0MB)Heap Usage:
New Generation (Eden + 1 Survivor Space):capacity = 120848384 (115.25MB)used = 5011248 (4.7790985107421875MB)free = 115837136 (110.47090148925781MB)4.146723219732918% used
Eden Space:capacity = 107479040 (102.5MB)used = 3005464 (2.8662338256835938MB)free = 104473576 (99.6337661743164MB)2.79632568359375% used
From Space:capacity = 13369344 (12.75MB)used = 2005784 (1.9128646850585938MB)free = 11363560 (10.837135314941406MB)15.002860274969363% used
To Space:capacity = 13369344 (12.75MB)used = 0 (0.0MB)free = 13369344 (12.75MB)0.0% used
concurrent mark-sweep generation:capacity = 939524096 (896.0MB)used = 406034024 (387.2242202758789MB)free = 533490072 (508.7757797241211MB)43.216988870075774% used38512 interned Strings occupying 3581472 bytes.
jstack命令
jstack命令用于导出Java应用程序的线程堆栈,语法为:
jstack [-l] <pid>
-l 选项用于打印锁的附加信息。
//打印出额外的锁信息,在发生死锁时可以用jstack -l pid来观察锁持有情况-m mixed mode,不仅会输出Java堆栈信息,还会输出C/C++堆栈信息(比如Native方法)
jstack -l 62147
对内容进行匹配一下,查看是否存在死锁。
该线程正在等待的资源:
该线程拥有的资源
jstat命令
每**秒一次显示进程号为**的java进程的GC情况
命令格式:jstat -gcutil pid interval(ms)
例如:
jstat -gcutil 62147 1000
参数说明如下:S0: 新生代中Survivor space 0区已使用空间的百分比
S1: 新生代中Survivor space 1区已使用空间的百分比
E: 新生代已使用空间的百分比
O: 老年代已使用空间的百分比
M: 元数据区已使用空间的百分比YGC: 从应用程序启动到当前,发生Yang GC 的次数
YGCT: 从应用程序启动到当前,Yang GC所用的时间【单位秒】
FGC: 从应用程序启动到当前,发生Full GC的次数
FGCT: 从应用程序启动到当前,Full GC所用的时间
GCT: 从应用程序启动到当前,用于垃圾回收的总时间【单位秒】
线上服务器的GC情况如下:
由此可见,是metaspace空间小导致的。