JVM(7)--java内置工具使用(2)

jmap

jmap命令(Java Memory Map)

1、介绍
打印出某个java进程(使用pid)内存内的,所有‘对象’的情况(如:产生那些对象,及其数量)。

可以输出所有内存中对象的工具,甚至可以将VM 中的heap,以二进制输出成文本。使用方法 jmap -histo pid。如果连用SHELL jmap -histo pid>a.log可以将其保存到文本中去,在一段时间后,使用文本对比工具,可以对比出GC回收了哪些对象。jmap -dump:format=b,file=outfile 3024可以将3024进程的内存heap输出出来到outfile文件里,再配合MAT(内存分析工具(Memory Analysis Tool),使用参见:http://blog.csdn.net/fenglibing/archive/2011/04/02/6298326.aspx)或与jhat (Java Heap Analysis Tool)一起使用,能够以图像的形式直观的展示当前内存是否有问题。
64位机上使用需要使用如下方式:
jmap -J-d64 -heap pid

2、命令格式
SYNOPSIS
jmap [ option ] pid
jmap [ option ] executable core
jmap [ option ] [server-id@]remote-hostname-or-IP

3、参数说明
1)、options:
executable Java executable from which the core dump was produced.
(可能是产生core dump的java可执行程序)
core 将被打印信息的core dump文件
remote-hostname-or-IP 远程debug服务的主机名或ip
server-id 唯一id,假如一台主机上多个远程debug服务
2)、基本参数:

  • -dump:[live,]format=b,file= 使用hprof二进制形式,输出jvm的heap内容到文件=. live子选项是可选的,假如指定live选项,那么只输出活的对象到文件.
  • -finalizerinfo 打印正等候回收的对象的信息.
  • -heap 打印heap的概要信息,GC使用的算法,heap的配置及wise heap的使用情况.
  • -histo[:live] 打印每个class的实例数目,内存占用,类全名信息. VM的内部类名字开头会加上前缀”*”. 如果live子参数加上后,只统计活的对象数量.
  • -permstat 打印classload和jvm heap长久层的信息. 包含每个classloader的名字,活泼性,地址,父classloader和加载的class数量. 另外,内部String的数量和占用内存数也会打印出来.
  • -F 强迫.在pid没有相应的时候使用-dump或者-histo参数. 在这个模式下,live子参数无效.
  • -h | -help 打印辅助信息
  • -J 传递参数给jmap启动的jvm.
    pid 需要被打印配相信息的java进程id,创业与打工的区别 - 博文预览,可以用jps查问.
  • 4、使用示例
    1)、[fenglb@ccbu-156-5 ~] jmaphisto4939[]2[fenglb@ccbu1565 ] jmap -dump:format=b,file=test.bin 4939
    Dumping heap to /home/fenglb/test.bin …
    Heap dump file created

    jinfo

    jinfo命令(Java Configuration Info)

    jinfo可以输出并修改运行时的java 进程的opts。用处比较简单,用于输出JAVA系统参数及命令行参数。用法是jinfo -opt pid 如:查看2788的MaxPerm大小可以用 jinfo -flag MaxPermSize 2788。

    jconsole

    jconsole命令(Java Monitoring and Management Console)

    jconsole:一个java GUI监视工具,可以以图表化的形式显示各种数据。并可通过远程连接监视远程的服务器VM。用java写的GUI程序,用来监控VM,并可监控远程的VM,非常易用,而且功能非常强。命令行里打 jconsole,选则进程就可以了。
    需要注意的就是在运行jconsole之前,必须要先设置环境变量DISPLAY,否则会报错误,Linux下设置环境变量如下:
    export DISPLAY=:0.0
    [root@localhost bin]# jconsole
    上两个图看一下:

    可以这里选择查看本地进程的状况,还是远程进程的状况。

     

    通过这张图可以看到内存、线程、类及CPU使用的一些情况。

    jvisualvm

    jvisualvm命令(Java Virtual Machine Monitoring, Troubleshooting, and Profiling Tool)

    jvisualvm同jconsole都是一个基于图形化界面的、可以查看本地及远程的JAVA GUI监控工具,Jvisualvm同jconsole的使用方式一样,直接在命令行打入Jvisualvm即可启动,不过Jvisualvm相比,界面更美观一些,数据更实时,上图为证:

    jhat

    jhat命令(Java Heap Analyse Tool)

    Jhat用于对JAVA heap进行离线分析的工具,他可以对不同虚拟机中导出的heap信息文件进行分析,如LINUX上导出的文件可以拿到WINDOWS上进行分析,可以查找诸如内存方面的问题,使用方式可以查看这篇文章:
    http://blog.csdn.net/gtuu0123/archive/2010/11/27/6039474.aspx
    不过jhat和MAT比较起来,就没有MAT那么直观了,MAT是以图形界面的方式展现结果,MAT的使用方式可以参看文章:
    http://blog.csdn.net/fenglibing/archive/2011/04/02/6298326.aspx

    Jdb

    Jdb命令(The Java Debugger)
    用来对core文件和正在运行的Java进程进行实时地调试,里面包含了丰富的命令帮助您进行调试,它的功能和Sun studio里面所带的dbx非常相似,但 jdb是专门用来针对Java应用程序的。现在应该说日常的开发中很少用到JDB了,因为现在的IDE已经帮我们封装好了,如使用ECLIPSE调用程序就是非常方便的,只要在非常特定的情况下可能会用到这个命令,如远程服务器的维护,没有IDE进行调试,那这个时候JDB应该可以帮上忙。

    Jstatd

    Jstatd命令(Java Statistics Monitoring Daemon)

    1、介绍
    jstatd是一个基于RMI(Remove Method Invocation)的服务程序,它用于监控基于HotSpot的JVM中资源的创建及销毁,并且提供了一个远程接口允许远程的监控工具连接到本地的JVM执行命令。
    jstatd是基于RMI的,所以在运行jstatd的服务器上必须存在RMI注册中心,如果没有通过选项”-p port”指定要连接的端口,jstatd会尝试连接RMI注册中心的默认端口。后面会谈到如何连接到一个默认的RMI内部注册中心,如何禁止默认的RMI内部注册中心的创建,以及如何启动一个外部注册中心。

    2、参数选项
    jstatd命令支持如下的选项:

  • -nr 如果RMI注册中心没有找到,不会创建一个内部的RMI注册中心。
  • -p port RMI注册中心的端口号,默认为1099。
  • -n rminame 默认为JStatRemoteHost;如果同一台主机上同时运行了多个jstatd服务,rminame可以用于唯一确定一个jstatd服务;这里需要注意一下,如果开启了这个选项,那么监控客户端远程连接时,必须同时指定hostid及vmid,才可以唯一确定要连接的服务,这个可以参看jps章节中列出远程服务器上Java进程的示例。
  • -J 用于传递jvm选项到由javac调用的java加载器中,例如,“-J-Xms48m”将把启动内存设置为48M,使用-J选项可以非常方便的向基于Java的开发的底层虚拟机应用程序传递参数。
  • 3、安全性
    jstatd服务只能监视具有适当的本地访问权限的JVM,因此jstatd进程与被监控的JVM必须运行在相同的用户权限中。但是有一些特殊的用户权限,如基于UNIX(TM)为系统的root用户,它有权限访问系统中所有JVM的资源,如果jstatd进程运行在这种权限中,那么它可以监视系统中的所有JVM,但是这也带来了额外的安全问题。
    jstatd服务不会对客户端进行任何的验证,因此运行了jstatd服务的JVMs,网络上的任何用户的都具有访问权限,这种暴露不是我们所希望的,因此在启动jstatd之前本地安全策略必须要加以考虑,特别是在生产环境中或者是在不安全的网络环境中。
    如果没有其他安全管理器被安装,jstatd服务将会安装一个RMISecurityPolicy的实例,因此需要在一个安全策略文件中指定,该策略文件必须符合的默认策略实施的策略文件语法。
    下面的这个示例策略将允许jstatd服务具有JVM全部的访问权限:

    grant codebase "file:${java.home}/../lib/tools.jar" {  
       permission java.security.AllPermission;  
    };  

    注:此处策略中的java.home,和JAVA_HOME不是一个概念,童鞋们不要搞错了,此处的java.home指的是JRE的路径,这个是Java的系统属性,不需要手工指定,通常是这个jdk下面的jre路径,即可以认为 java.home {JAVA_HOME}/jre是等价,如果想查看这个变量的值,可以任意找一个运行着的Java应用,找到它的PID,然后通过如下jinfo命令查看就可以查看到java.home的值:

    jinfo ${PID}|grep java.home  

    也可以在Java代码中通过如下方式获取到:

    System.out.println(System.getProperty("java.home"))  

    将上面的策略内容拷贝一个文件中,文件名可以随意取,为了形象我们将文件名命名为jstatd.all.policy,文件存放的路径也可以随意,只有你当前登陆的用户具有访问权限就可以,然后执行以下命令就可以启动jstatd服务:

    jstatd -J-Djava.security.policy=jstatd.all.policy  

    如果是在具有安全限制的环境中,jstatd的策略安全一定要设置得当,并且只允许受信任的服务器或者网络访问,以免遭受网络攻击,如果存在安全隐患,最好不要启动jstatd服务,就在本地使用jstat及jps等工具对JVM进行监控了。

    4、示例
    4.1、使用内部RMI注册中心
    下面这个示例演示了通过内部RMI注册中心启动jstatd,这个示例假设没有其它的服务绑定到默认的RMI注册中心端口(默认端口是1099)。
    [plain] view plain copy 在CODE上查看代码片派生到我的代码片
    jstatd -J-Djava.security.policy=jstatd.all.policy
    注:如果基于默认端口1099的RMI注册中心原来没有被启动过,那么上面运行的命令首先会启动端口为1099的RMI注册中心,然后再启动jstatd服务,此时即使jstatd停止了,RMI注册中心也不会停止;如果是再次执行上面的命令,就不会再次启动RMI注册中心,jstatd会直接注册到注册中心。

    4.2、使用外部的RMI注册中心
    这个示例演示了使用一个外部的RMI注册中心来启动jstatd,如果默认的内部注册中心已经被启动了,下面的这个示例就会抛出“端口1099已经被占用”的异常,因为它尝试在1099端口启动外部RMI注册中心:

    rmiregistry&jstatd -J-Djava.security.policy=all.policy  
    这个示例演示了使用一个外部的RMI注册中心来启动jstatd,此注册中心的端口为2020:
    

    [plain] view plain copy 在CODE上查看代码片派生到我的代码片
    rmiregistry 2020&jstatd -J-Djava.security.policy=all.policy -p 2020
    这个示例演示了使用一个外部的RMI注册中心来启动jstatd,此注册中心的端口为2020,并且绑定到RMI注册中心的名为AlternateJstatdServerName:

    rmiregistry 2020&jstatd -J-Djava.security.policy=all.policy -p 2020 -n AlternateJstatdServerName  

    注:这个端口为2020的RMI注册中心,我们会在jps章节中使用到。

    4.3、禁止内部RMI注册中心的创建
    这个示例演示了jstatd在启动的时候,如果没有找到默认的RMI注册中心,也不会创建默认的注册中心。这个示例中如果没有RMI注册中心在运行,此示例就会报错,如果存在就会正常运行:

    jstatd -J-Djava.security.policy=all.policy -nr  

    4.4、开启RMI日记记录
    这个示例演示的是jstatd运行在开启了日志记录功能的RMI注册中,这个对于问题查找或监控服务状态非常有用:

    jstatd -J-Djava.security.policy=all.policy -J-Djava.rmi.server.logCalls=true  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值