java内存查看与分析
核心提示:其实java自己就提供了很多内存监控的小工具,下面列举的工具只是一小部分,仔细研究下
jdk的工具。
业界有很多强大的javaprofile的工具,比如Jporfiler,yourkit,这些收费的东西
我就不想说了,想说的是,其实java自己就提供了很多内存监控的小工具,下面列举的工具
只是一小部分,仔细研究下jdk的工具,还是蛮有意思的呢:)
1:gc日志输出
在jvm启动参数中加入-XX:+PrintGC-XX:+PrintGCDetails-XX:+PrintGCTimestamp
s-XX:+PrintGCApplicationStopedTime,jvm将会按照这些参数顺序输出gc概要信息,详
细信息,gc时间信息,gc造成的应用暂停时间。如果在刚才的参数后面加入参数-Xloggc:
文件路径,gc信息将会输出到指定的文件中。其他参数还有
-verbo:gc和-XX:+PrintTenuringDistribution等。
2:jconsole
jconsole是jdk自带的一个内存分析工具,它提供了图形界面。可以查看到被监控的j
vm的内存信息,线程信息,类加载信息,MBean信息。
jconsole位于jdk目录下的bin目录,在windows下是jcons,在unix和linu
x下是jconsol,jconsole可以监控本地应用,也可以监控远程应用。要监控本地应
用,执行jconsolepid,pid就是运行的java进程id,如果不带上pid参数,则执行jcon
sole命令后,会看到一个对话框弹出,上面列出了本地的java进程,可以选择一个进行监
控。如果要远程监控,则要在远程服务器的jvm参数里加入一些东西,因为jconsole的远程
监控基于jmx的,关于jconsole详细用法,请见专门介绍jconsle的文章,我也会在博客里
专门详细介绍jconsole。
3:jviusalvm
在JDK6update7之后,jdk推出了另外一个工具:jvisualvm,java可视化虚拟机,它
不但提供了jconsole类似的功能,还提供了jvm内存和cpu实时诊断,还有手动dump出j
vm内存情况,手动执行gc。
和jconsole一样,运行jviusalvm,在jdk的bin目录下执行jviusalvm,windows下
是jviusa,linux和unix下是jviusalv。
4:jmap
jmap是jdk自带的jvm内存分析的工具,位于jdk的bin目录。jdk1.6中jmap命令用法
:
Usage:
jmap-histo
(toconnecttorunningprocessandprinthistogramofjavaobjectheap
jmap-dump:
(toconnecttorunningprocessanddumpjavaheap)
dump-options:
format=bbinarydefault
file=
Example:jmap-dump:format=b,file=
jmap-histo
命令,屏幕显示:
num#instances#bytesclassname
----------------------------------------------
1:242062791864
2:223712145216[C
3:242061940648
4:19511364496
5:265431282560
6:63771081744[B
7:1793909688
8:1471614624
9:14581548336[Ljava.t;
10:3863513640[I
11:2067749624g
12:3621312776[Ljava.ap$Entry;
13:333526680d
14:825626419tStreamClass$WeakClassKey
15:706622611ap$Entry
16:2355173304[S
17:168716195
18:2769150112[[I
19:356314252ap
20:556213348ap$Entry
Total23901917140408
为了方便查看,我删掉了一些行。从上面的信息很容易看出,#instance指的是对象数
量,#bytes指的是这些对象占用的内存大小,classname指的是对象类型。
再看jmap的dump选项,这个选项是将jvm的堆中内存信息输出到一个文件中,在我本
机执行
jmap-dump:file=c:340
注意340是我本机的java进程pid,dump出来的文件比较大有10几M,而且我只是开了
tomcat,跑了一个很简单的应用,且没有任何访问,可以想象,大型繁忙的服务器上,dum
p出来的文件该有多大。需要知道的是,dump出来的文件信息是很原始的,绝不适合人直接
观看,而jmap-histo显示的内容又太简单,例如只显示某些类型的对象占用多大内存,以
及这些对象的数量,但是没有更详细的信息,例如这些对象分别是由谁创建的。那这么说,
dump出来的文件有什么用呢?当然有用,因为有专门分析jvm的内存dump文件的工具。
5:jhat
上面说了,有很多工具都能分析jvm的内存dump文件,jhat就是sunjdk6及以上版本
自带的工具,位于jdk的bin目录,执行jhat-J-Xmx512m[file],file就是dump文件
路径。jhat内置一个简单的web服务器,此命令执行后,jhat在命令行里显示分析结果的访
问地址,可以用-port选项指定端口,具体用法可以执行jhat-heap查看帮助信息。访问指
定地址后,就能看到页面上显示的信息,比jmap-histo命令显示的丰富得多,更为详细。
6:eclip内存分析器
上面说了jhat,它能分析jvm的dump文件,但是全部是文字显示,eclipmemorya
nalyzer,是一个eclip提供用于分析jvm堆dump的插件,它的分析速度比jhat快,分析
结果是图形界面显示,比jhat的可读性更高。其实jvisualvm也可以分析dump文件,也是有
图形界面显示的。
7:jstat
如果说jmap倾向于分析jvm内存中对象信息的话,那么jsta就是倾向于分析jvm内存
的gc情况。都是jvm内存分析工具,但显然,它们是从不同维度来分析的。jsat常用的参数
有很多,如-gc,-gcutil,-gccau,这些选项具体作用可查看jsat帮助信息,我经常用-g
cutil,这个参数的作用不断的显示当前指定的jvm内存的垃圾收集的信息。
我在本机执行jstat-gcutil34010000,这个命令是每个10秒钟输出一次jvm的gc
信息,10000指的是间隔时间为10000毫秒。屏幕上显示如下信息(我只取了第一行,因为
是按的一定频率显示,所以实际执行的时候,会有很多行):
S0S1EOPYGCYGCTFGCFGCTGCT
54.620.0042.8743.5286.2417925.093337.67012.763
额……怎么说呢,要看懂这些信息代表什么意思,还必须对jvm的gc机制有一定的了解
才行啊。其实如果对sun的hotspotjvm的gc比较了解的人,应该很容易看懂这些信息,
但是不清楚gc机制的人,有点莫名其妙,所以在这里我还是先讲讲sun的jvm的gc机制吧。
说到gc,其实不仅仅只是java的概念,其实在java之前,就有很多语言有gc的概念了,
gc嘛就是垃圾收集的意思,更多的是一种算法性的东西,而跟具体语言没太大关系,所以
关于gc的历史,gc的主流算法我就不讲了,那扯得太远了,扯得太远了就是扯淡。sun现在
的jvm,内存的管理模型是分代模型,所以gc当然是分代收集了。分代是什么意思呢?就是
将对象按照生命周期分成三个层次,分别是:新生代,旧生代,持久代。对象刚开始分配
的时候,大部分都在新生代,当新生代gc提交被触发后了,执行一次新生代范围内的gc,
这叫minorgc,如果执行了几次minorgc后,还有对象存活,将这些对象转入旧生代,因
为这些对象已经经过了组织的重重考验了哇。旧生代的gc频率会更低一些,如果旧生代执
行了gc,那就是fullgc,因为不是局部gc,而是全内存范围的gc,这会造成应用停顿,因
为全内存收集,必须封锁内存,不许有新的对象分配到内存,持久代就是一些jvm期间,
基本不会消失的对象,例如class的定义,jvm方法区信息,例如静态块。需要主要的是,
新生代里又分了三个空间:eden,susvivor0,susvivor1,按字面上来理解,就是伊甸园
区,幸存1区,幸存2区。新对象分配在eden区中,eden区满时,采用标记-复制算法,即
检查出eden区存活的对象,并将这些对象复制到是s0或s1中,然后清空eden区。jvm的
gc说开来,不只是这么简单,例如还有串行收集,并行收集,并发收集,还有着名的火车
算法,不过那说得太远了,现在对这个有大致了解就好。说到这里,再来看一下上面输出
的信息:
S0S1EOPYGCYGCTFGCFGC
TGCT
54.620.0042.8743.5286.2417925.093337.67012.763
S0:新生代的susvivor0区,空间使用率为5462%
S1:新生代的susvivor1区,空间使用率为0.00%(因为还没有执行第二次minor收集)
E:eden区,空间使用率42.87%
O:旧生代,空间使用率43.52%
P:持久带,空间使用率86.24%
YGC:minorgc执行次数1792次
YGCT:minorgc耗费的时间5.093毫秒
FGC:fullgc执行次数33
FGCT:fullgc耗费的时间7.670毫秒
GCT:gc耗费的总时间12.763毫秒
怎样选择工具
上面列举的一些工具,各有利弊,其实如果在开发环境,使用什么样的工具是无所谓
的,只要能得到结果就好。但是在生产环境里,却不能乱选择,因为这些工具本身就会耗
费大量的系统资源,如果在一个生产服务器压力很大的时候,贸然执行这些工具,可能会
造成很意外的情况。最好不要在服务器本机监控,远程监控会比较好一些,但是如果要远
程监控,服务器端的启动脚本要加入一些jvm参数,例如用jconsloe远程监控tomcat或j
boss等,都需要设置jvm的jmx参数,如果仅仅只是分析服务器的内存分配和gc信息,强
烈推荐,先用jmap导出服务器端的jvm的堆dump文件,然后再用jhat,或者jvisualvm,
或者eclip内存分析器来分析内存状况。
原文出处:中软卓越.comwww.5retc.com
本文发布于:2023-01-04 05:22:38,感谢您对本站的认可!
本文链接:http://www.wtabcd.cn/fanwen/fan/90/88847.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |