java虚拟机的一些内存监控

内存溢出之后,分析原因往往有些困难,这里在启动jvm的时候可以增加一些参数,等内存溢出发生时jvm会帮我们记录当时的快照

这是我模拟内存溢出的启动参数:

-Xmx64m -Xms32m -Xmn16m -Xss8m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/Users/liucheng/开发/vm/VMDemo.hprof -XX:OnOutOfMemoryError="/Users/liucheng/开发/vm/sh/clear.sh VMDemo"

设置jvm的内存大小相关参数我不说了,重点是后面几个参数

-XX:+HeapDumpOnOutOfMemoryError 当jvm发生内存溢出(om溢出)的时候进行快照记录;

-XX:HeapDumpPath 设置快照路径(可以是路径,也可以是具体到快照文件名),如果不设置,默认会在当前工作空间生成快照。

-XX:OnOutOfMemoryError 设置发生内存溢出后调用一个sh脚本(调用脚本更多的目的是将快照文件转移到其他服务器,因为快照文件非常大,经常发生om又没有及时清理快照文件,会很快让磁盘被塞满)

ok,开始正题,导致堆内存溢出的代码:

java虚拟机的一些内存监控_第1张图片

执行结果:

java虚拟机的一些内存监控_第2张图片

附上clear.sh脚本:

java虚拟机的一些内存监控_第3张图片

生成的快照文件:

java虚拟机的一些内存监控_第4张图片

如何分析快照文件,这里我推荐3种方式:

一、使用java自带的命令  jhat

 

执行 jhat -port 8888 VMDemo.hprof

不指定 -port 默认7000

访问 http://localhost:8888

这种方式会将快照信息以web的方式展现,但是展示信息有限。

java虚拟机的一些内存监控_第5张图片

浏览器访问 http://localhost:7000

java虚拟机的一些内存监控_第6张图片

这里面每个链接操作都有相应的说明,有兴趣的可以百度了解,这种方式我不太喜欢,没有过多了解

二、使用mat工具分析

在这里下载 https://www.eclipse.org/mat/

mat载入快照文件后:

java虚拟机的一些内存监控_第7张图片

这个把内存情况用饼形图表达的很清楚。

更多信息

java虚拟机的一些内存监控_第8张图片

 

java虚拟机的一些内存监控_第9张图片

通过上面这张图可以看出代码中的 list塞入了1407条类型为string的数据

三、使用visualVM

装载进快照文件后,选择线程项

java虚拟机的一些内存监控_第10张图片

 

以上是都是快照已经生成,事后来找问题的方案,针对正在运行中的jvm来说,可以用以下方式监控jvm各种参数起到调试作用。

一、使用visualVM

这种方式我就不多说了,除了本地也可以远程连接,这种都懂,下面我要介绍的是才是好用的

java虚拟机的一些内存监控_第11张图片

二、使用java自带的jconsole工具

运行 jconsole 稍等一下下出来一个界面

java虚拟机的一些内存监控_第12张图片

 

这次连接一个远程的jvm来示例

远程连接之前的准备工作:

 

在服务器上执行 hostname -i 得到的ip应该是-Djava.rmi.server.hostname的设置ip

然后用如下命令启动:

java -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9990 -Dcom.sun.management.jmxremote.rmi.port=9990 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.rmi.server.hostname=al.cloud.net -jar eureka-0.0.1-SNAPSHOT.jar

这里公网ip就不对外公开了,我用本地hosts  al.cloud.net映射了公网服务器ip,设置成你自己要连接的服务器上公网ip即可。

以下是参数解释

 

-Dcom.sun.management.jmxremote 布尔 是否支持远程JMX访问,默认true

-Dcom.sun.management.jmxremote.port 数值 监听端口号,方便远程访问

-Dcom.sun.management.jmxremote.rmi.port 数值 rmi端口,方便远程访问

-Dcom.sun.management.jmxremote.authenticate 布尔 是否需要开启用户认证,默认开启

-Dcom.sun.management.jmxremote.ssl 布尔 是否对连接开启SSL加密,默认开启

-Dcom.sun.management.jmxremote.access.file 路径 对访问用户的权限授权的文件的路径,默认路径JRE_HOME/lib/management/jmxremote.access

-Dcom.sun.management.jmxremote. password.file 路径 设置访问用户的用户名和密码,默认路径JRE_HOME/lib/management/ jmxremote.password

 

本地来测试一下服务器上的端口是否可以正常通信  telnet al.cloud.net 9990

开始连接

java虚拟机的一些内存监控_第13张图片

java虚拟机的一些内存监控_第14张图片

出现这个是因为ssl项设置为false了 不管它继续点击连接

java虚拟机的一些内存监控_第15张图片

后面的都知道操作了。

其实还有一些java自带的命令方式查看

比如:

 

当前线程所有堆栈信息 jstack pid

当前线程的相关信息输出到日志 kill -3 pid

查看gc信息

jstat -gc pid

  • S0C : survivor0区的总容量
  • S1C : survivor1区的总容量
  • S0U : survivor0区已使用的容量
  • S1C : survivor1区已使用的容量
  • EC : Eden区的总容量
  • EU : Eden区已使用的容量
  • OC : Old区的总容量
  • OU : Old区已使用的容量
  • PC 当前perm的容量 (KB)
  • PU perm的使用 (KB)
  • YGC : 新生代垃圾回收次数
  • YGCT : 新生代垃圾回收时间
  • FGC : 老年代垃圾回收次数
  • FGCT : 老年代垃圾回收时间
  • GCT : 垃圾回收总消耗时间

 

gc信息 2000ms内输出一次 总共输出20次

jstat -gc pid 2000 20

 

同-gc,还会输出Java堆各区域使用到的最大、最小空间

jstat -gccapacity 进程id

  • NGCMN : 新生代占用的最小空间
  • NGCMX : 新生代占用的最大空间
  • OGCMN : 老年代占用的最小空间
  • OGCMX : 老年代占用的最大空间
  • OGC:当前年老代的容量 (KB)
  • OC:当前年老代的空间 (KB)
  • PGCMN : perm占用的最小空间
  • PGCMX : perm占用的最大空间

 

同-gc,还会输出的是已使用空间占总空间的百分比

jstat -gcutil pid

 

垃圾收集统计概述(同-gcutil),附加最近两次垃圾回收事件的原因

jstat -gccause pid

  • LGCC:最近垃圾回收的原因
  • GCC:当前垃圾回收的原因

查看JIT编译过的方法数量耗时

jstat -compiler pid

  • Compiled : 编译数量
  • Failed : 编译失败数量
  • Invalid : 无效数量
  • Time : 编译耗时
  • FailedType : 失败类型
  • FailedMethod : 失败方法的全限定名

查看类装载数量

jstat -class pid

  • Loaded : 加载class的数量
  • Bytes : class字节大小
  • Unloaded : 未加载class的数量
  • Bytes : 未加载class的字节大小
  • Time : 加载时间
欢迎关注我的个人公众号 欢迎关注我的个人公众号

你可能感兴趣的:(java基础)