java现网性能GC相关

参考:
https://www.cnblogs.com/ncy1/p/9692733.html
http://www.itsoku.com/article/124

1.内存泄漏问题初步定位

  1. 使用jsp命令,结合ps -ef | grep xx、top等命令获取程序执行的进程号
    可以使用下列命令查看启动参数:
    jcmd pid VM.flags
    --VM.flags是jcmd的参数,可以通过换其他参数查其他的信息
    jinfo -flags pid
    --去掉flags参数可以查到更多的信息
    
  2. 使用 jstat -gcutil 快速查看系统当前实时GC情况
    命令格式:jstat  -gcutil  <pid>  <period> 
    命令样例:jstat  -gcutil  26885 3s  
    ------> 监控进程26885的GC情况, 每3s输出一条记录。
    ps:补充几个参数
    查询老年代等内存占用大小信息
    jstat -gcold  <pid>  <period> 
    查询结果OC(总)、OU(使用)
    查询新生代内存占用信息
    jstat -gcnewcapacity  <pid>  <period> 
    查询结果NGCMX(最大总)、NGC(使用)
    
    jstat  -gcutil  26885 3s命令执行结果
  3. 使用 jmap -histo 命令定位内存泄露具体对象
    该命令展示所有类的实例个数以及内存用量情况,并按照使用量降序输出,一般自己写的类有内存泄露,那会名列前茅。
    命令1:jmap -histo  <pid>
    命令样例:jmap  -histo 26885 | head  -n  20
    输出对应进程当前所有存活对象的堆内存占用情况,找到"突出" 的嫌疑类。
    
    命令2:jmap  -histo:live  <pid>
    带上live,会触发一次Full GC后再输出结果,实际上就是回收了无用的对象,输出真正存活的对象情况。如果嫌疑类名实例数不减,那么十有八九这个类就是导致内存泄露根因。
    
    要点:两个命令对比观察Full GC后,实例数不减的类,重点关注排在前面的几个自己写的类名。
    
  4. 使用 jmap -dump:file 导出堆内存数据。
    通过3,一般可以定位出代码位置,但代码中很多地方引用了这个类,则要导出 Dump 文件,进一步分析泄露对象的GCRoot 。
    命令:jmap  -dump:file=<文件名> <pid>
    样例:jmap  -dump:file=xxx.dump  26885
    
    分析dump文件的工具:除了JDK自带的 jhat , jvisualvm ,还有第三方的MAT,jprofiler等。
    内存泄露的话,dump文件也会很大,为了防止卡死,一般会将Xmx控制在一个合适的大小(2G) ,重现问题后, 再导出dump 。
    要点:将Xmx设小一点,再导出dump。
  5. jhat分析dump文件,寻找GC Root。
    因为网络拷贝大容量的dump文件诸多不便,所以需要现网直接分析dump文件,jhat可以启动一个http服务,提供页面远程分析对象引用情况。
    命令:jhat  -J-Xmx2G  -port <port> <dump文件>
    样例:jhat  -J-Xmx2G  xxx.dump
    其中Xmx2G代表使用2G堆内存运行jhat
    
    下一步可浏览器分析了,URL:http://ip:7000
    要点:首先链接到嫌疑类的具体某个对象页面,分析这个对象的引用情况是否正常,再通过“Reference chains from Rootset ”获取所有的GC Root ,进而定位到具体代码位置。

2.jhat简单分析展示

jhat简单分析
1、执行jhat启动dump文件的解析在这里插入图片描述
2、访问jhat启动的页面
3、通过“Show heap histogram”找到内存中总容量最大的对象
在这里插入图片描述
4、通过“Execute Object Query Language (OQL) query”使用类似于SQL的语法对内存对象进行查询统计

jhat页面“Other Queries”下选项大致描述:
All classes including platform                                      显示出堆中所包含的所有的类
Show all members of the rootset                                     从根集能引用到的对象
Show instance counts for all classes (including platform)           显示所有类(包括平台)的实例计数
Show instance counts for all classes (excluding platform)           显示所有类(去除平台)的实例计数
Show heap histogram                                                 堆实例的分布表
Show finalizer summary
Execute Object Query Language (OQL) query                           执行对象查询语句

ps:
OQL使用示例:

输入内容如:select s from java.lang.String s where s.count > 100,来查询长度大于100的字符串

OQL使用说明:

详细的OQL可点击页面中的“OQL help”查看
jhat中的OQL(对象查询语言) ,文档可以查看:http://localhost:7000/oqlhelp/
如果需要根据某些条件来过滤或查询堆的对象,这是可能的,可以在jhat的html页面中执行OQL,来查询符合条件的对象

基本语法: 
select <javascript expression to select>
[from [instanceof] <class name> <identifier>]
[where <javascript boolean expression to filter>]

解释: 
(1)class name是java类的完全限定名,如:java.lang.String, java.util.ArrayList, [C是char数组, [Ljava.io.File是java.io.File[]
(2)类的完全限定名不足以唯一的辨识一个类,因为不同的ClassLoader载入的相同的类,它们在jvm中是不同类型的
(3)instanceof表示也查询某一个类的子类,如果不明确instanceof,则只精确查询class name指定的类
(4)from和where子句都是可选的
(5)java域表示:obj.field_name;java数组表示:array[index]

举例: 
(1)查询长度大于100的字符串
select s from java.lang.String s where s.count > 100

(2)查询长度大于256的数组
select a from [I a where a.length > 256

(3)显示匹配某一正则表达式的字符串
select a.value.toString() from java.lang.String s where /java/(s.value.toString())

(4)显示所有文件对象的文件路径
select file.path.value.toString() from java.io.File file

(5)显示所有ClassLoader的类名
select classof(cl).name from instanceof java.lang.ClassLoader cl

(6)通过引用查询对象
select o from instanceof 0xd404d404 o

built-in对象 -- heap 
(1)heap.findClass(class name) -- 找到类
select heap.findClass("java.lang.String").superclass

(2)heap.findObject(object id) -- 找到对象
select heap.findObject("0xd404d404")

(3)heap.classes -- 所有类的枚举
select heap.classes

(4)heap.objects -- 所有对象的枚举
select heap.objects("java.lang.String")

(5)heap.finalizables -- 等待垃圾收集的java对象的枚举

(6)heap.livepaths -- 某一对象存活路径
select heaplivepaths(s) from java.lang.String s

(7)heap.roots -- 堆根集的枚举

辨识对象的函数 
(1)classof(class name) -- 返回java对象的类对象
select classof(cl).name from instanceof java.lang.ClassLoader cl

(2)identical(object1,object2) -- 返回是否两个对象是同一个实例
select identical(heap.findClass("java.lang.String").name, heap.findClass("java.lang.String").name)

(3)objectid(object) -- 返回对象的id
select objectid(s) from java.lang.String s

(4)reachables -- 返回可从对象可到达的对象
select reachables(p) from java.util.Properties p -- 查询从Properties对象可到达的对象
select reachables(u, "java.net.URL.handler") from java.net.URL u -- 查询从URL对象可到达的对象,但不包括从URL.handler可到达的对象

(5)referrers(object) -- 返回引用某一对象的对象
select referrers(s) from java.lang.String s where s.count > 100

(6)referees(object) -- 返回某一对象引用的对象
select referees(s) from java.lang.String s where s.count > 100

(7)refers(object1,object2) -- 返回是否第一个对象引用第二个对象
select refers(heap.findObject("0xd4d4d4d4"),heap.findObject("0xe4e4e4e4"))

(8)root(object) -- 返回是否对象是根集的成员
select root(heap.findObject("0xd4d4d4d4")) 

(9)sizeof(object) -- 返回对象的大小
select sizeof(o) from [I o

(10)toHtml(object) -- 返回对象的html格式
select "<b>" + toHtml(o) + "</b>" from java.lang.Object o

(11)选择多值
select {name:t.name?t.name.toString():"null",thread:t} from instanceof java.lang.Thread t

数组、迭代器等函数 
(1)concat(enumeration1,enumeration2) -- 将数组或枚举进行连接
select concat(referrers(p),referrers(p)) from java.util.Properties p

(2)contains(array, expression) -- 数组中元素是否满足某表达式
select p from java.util.Properties where contains(referres(p), "classof(it).name == 'java.lang.Class'")
返回由java.lang.Class引用的java.util.Properties对象
built-in变量
it -- 当前的迭代元素
index -- 当前迭代元素的索引
array -- 被迭代的数组

(3)count(array, expression) -- 满足某一条件的元素的数量
select count(heap.classes(), "/java.io./(it.name)")

(4)filter(array, expression) -- 过滤出满足某一条件的元素
select filter(heap.classes(), "/java.io./(it.name)")

(5)length(array) -- 返回数组长度
select length(heap.classes())

(6)map(array,expression) -- 根据表达式对数组中的元素进行转换映射
select map(heap.classes(),"index + '-->' + toHtml(it)")

(7)max(array,expression) -- 最大值, min(array,expression)
select max(heap.objects("java.lang.String"),"lhs.count>rhs.count")
built-in变量
lhs -- 左边元素
rhs -- 右边元素

(8)sort(array,expression) -- 排序
select sort(heap.objects('[C'),'sizeof(lhs)-sizeof(rhs)')

(9)sum(array,expression) -- 求和
select sum(heap.objects('[C'),'sizeof(it)')

(10)toArray(array) -- 返回数组

(11)unique(array) -- 唯一化数组
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值