查找Java应用内指定类实例数量
背景
最近,用户反馈我们系统某个业务慢。
我们通过使用arthas trace追踪到是ch.qos.logback.core.OutputStreamAppender.writeBytes方法耗时长,而OutputStreamAppender是ch.qos.logback.core.ConsoleAppender的父类。
我们系统日志组件采用logback,输出到控制台,高并发下ConsoleAppender写日志慢。由此,我们想确定ConsoleAppender是否是单例?(虽然按常理思考,它肯定是单例)
方法
简单方法,jmap
jmap是JDK提供的工具,通过jmap -histo 可以查看java进程类对象信息。它的各项输出含义:
- num 按占用空间排序的序号
- instances 实例数量
- bytes 占用空间
- class name 类名称
jmap -histo 7|grep ConsoleAppender,输出
4036: 1 72 ch.qos.logback.core.ConsoleAppender
instances是1,说明ch.qos.logback.core.ConsoleAppender是单例。
复杂方法,dump堆分析
按下面步骤,
- jmap -dump:live,format=b,file=heap.bin
- Eclipse Memory Analyzer打开heap.bin
- "dominator_tree"菜单,搜索框输入类名 或者 "OQL"菜单,输入select * from 全限定类名(如ch.qos.logback.core.ConsoleAppender);找到的实例会全部列出来,一行就是一个实例,总数需要自己计算。