JDK内置工具使用

JDK内置工具使用

一、jps命令(Java Virtual Machine Process Status Tool)

二、jstack命令(Java Stack Trace)

三、jstat命令(Java Virtual Machine Statistics Monitoring Tool)

四、jmap命令(Java Memory Map)

五、jinfo命令(Java Configuration Info)

六、jconsole命令(Java Monitoring and Management Console)

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

八、jhat命令(Java Heap Analyse Tool)

九、Jstatd命令(Java Statistics Monitoring Daemon)

十、MAT(Memory Analyzer Tool)工具入门介绍

 

 

===================== jps =================================

1、介绍

    用来查看基于HotSpot的JVM里面中,所有具有访问权限的Java进程的具体状态, 包括进程ID,进程启动的路径及启动参数等等,与unix上的ps类似,只不过jps是用来显示java进程,可以把jps理解为ps的一个子集。

    使用jps时,如果没有指定hostid,它只会显示本地环境中所有的Java进程;如果指定了hostid,它就会显示指定hostid上面的java进程,不过这需要远程服务上开启了jstatd服务,可以参看前面的jstatd章节来启动jstad服务。

 

2、命令格式

jps [ options ] [ hostid ]

 

3、常用参数说明

-q 忽略输出的类名、Jar名以及传递给main方法的参数,只输出pid。

-m 输出传递给main方法的参数,如果是内嵌的JVM则输出为null。

-l 输出应用程序主类的完整包名,或者是应用程序JAR文件的完整路径。

-v 输出传给JVM的参数。

-V 输出通过标记的文件传递给JVM的参数(.hotspotrc文件,或者是通过参数-XX:Flags=<filename>指定的文件)。

-J 用于传递jvm选项到由javac调用的java加载器中,例如,“-J-Xms48m”将把启动内存设置为48M,使用-J选项可以非常方便的向基于Java的开发的底层虚拟机应用程序传递参数。

 

4、服务器标识

hostid指定了目标的服务器,它的语法如下:

[protocol:][[//]hostname][:port][/servername]

protocol - 如果protocol及hostname都没有指定,那表示的是与当前环境相关的本地协议,如果指定了hostname却没有指定protocol,那么protocol的默认就是rmi。

hostname - 服务器的IP或者名称,没有指定则表示本机。

port - 远程rmi的端口,如果没有指定则默认为1099。

Servername - 注册到RMI注册中心中的jstatd的名称。

 

5、使用示例

5.1、列出本地的Java进程

不带任何参数

fenglibin@libin:~$ jps

11644 Main

1947 

12843 Jps

带-v参数

fenglibin@libin:~$ jps -v

11644 Main -agentlib:jdwp=transport=dt_socket,suspend=y,address=localhost:43467 -Dfile.encoding=GBK

1947  -Dosgi.requiredJavaVersion=1.5 -XX:MaxPermSize=256m -Xms40m -Xmx512m

12858 Jps -Denv.class.path=/home/fenglibin/java6/lib/dt.jar:/home/fenglibin/java6/lib/tools.jar::/usr/bin/libtool:/usr/bin/autoconf:/usr/local/BerkeleyDB.4.8/lib -Dapplication.home=/home/fenglibin/java6 -Xms8m

带-l参数

fenglibin@libin:~$ jps -l

11644 com.alibaba.china.webww.core.Main

12870 sun.tools.jps.Jps

1947

 

 

5.2、列出远程的Java进程

在jstatd章节,我们有通过:

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

启动了名为AlternateJstatdServerName的jstatd服务,那么我们此时就可以通过该服务列出其有权限访问的Java进程。

fenglibin@libin:~$ jps 10.1.1.234:2020/AlternateJstatdServerName

29556 Bootstrap

28671 WSPreLauncher

2602 RegistryImpl

18272 Test

2603 Jstatd

 

 

 

 ===================== jstack =============================

1、介绍

jstack用于打印出给定的java进程ID或core file或远程调试服务的Java堆栈信息,如果是在64位机器上,需要指定选项"-J-d64",Windows的jstack使用方式只支持以下的这种方式:

jstack [-l] pid

如果java程序崩溃生成core文件,jstack工具可以用来获得core文件的java stack和native stack的信息,从而可以轻松地知道java程序是如何崩溃和在程序何处发生问题。另外,jstack工具还可以附属到正在运行的java程序中,看到当时运行的java程序的java stack和native stack的信息, 如果现在运行的java程序呈现hung的状态,jstack是非常有用的。

2、命令格式
jstack [ option ] pid
jstack [ option ] executable core
jstack [ 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)、基本参数:

-F当’jstack [-l] pid’没有相应的时候强制打印栈信息

-l长列表. 打印关于锁的附加信息,例如属于java.util.concurrent的ownable synchronizers列表.

-m打印java和native c/c++框架的所有栈信息.

-h | -help打印帮助信息

pid 需要被打印配置信息的java进程id,可以用jps查询.

4、使用示例

 

 

 

 

===================== jstat ===========================

 1、介绍

Jstat用于监控基于HotSpot的JVM,对其堆的使用情况进行实时的命令行的统计,使用jstat我们可以对指定的JVM做如下监控:

- 类的加载及卸载情况

- 查看新生代、老生代及持久代的容量及使用情况

- 查看新生代、老生代及持久代的垃圾收集情况,包括垃圾回收的次数及垃圾回收所占用的时间

- 查看新生代中Eden区及Survior区中容量及分配情况等

jstat工具特别强大,它有众多的可选项,通过提供多种不同的监控维度,使我们可以从不同的维度来了解到当前JVM堆的使用情况。详细查看堆内各个部分的使用量,使用的时候必须加上待统计的Java进程号,可选的不同维度参数以及可选的统计频率参数。

它主要是用来显示GC及PermGen相关的信息,如果对GC不怎么了解,先看这篇文章:http://blog.csdn.net/fenglibing/archive/2011/04/13/6321453.aspx,否则其中即使你会使用jstat这个命令,你也看不懂它的输出。

 

2、语法

     jstat [ generalOption | outputOptions vmid [interval[s|ms] [count]] ]

    generalOption - 单个的常用的命令行选项,如-help, -options, 或 -version。

    outputOptions -一个或多个输出选项,由单个的statOption选项组成,可以和-t, -h, and -J等选项配合使用。

    statOption:

    根据jstat统计的维度不同,可以使用如下表中的选项进行不同维度的统计,不同的操作系统支持的选项可能会不一样,可以通过-options选项,查看不同操作系统所支持选项,如:

OptionDisplays...
class 用于查看类加载情况的统计
compiler 用于查看HotSpot中即时编译器编译情况的统计
gc 用于查看JVM中堆的垃圾收集情况的统计
gccapacity 用于查看新生代、老生代及持久代的存储容量情况
gccause 用于查看垃圾收集的统计情况(这个和-gcutil选项一样),如果有发生垃圾收集,它还会显示最后一次及当前正在发生垃圾收集的原因。
gcnew 用于查看新生代垃圾收集的情况
gcnewcapacity 用于查看新生代的存储容量情况
gcold 用于查看老生代及持久代发生GC的情况
gcoldcapacity 用于查看老生代的容量
gcpermcapacity 用于查看持久代的容量
gcutil 用于查看新生代、老生代及持代垃圾收集的情况
printcompilation HotSpot编译方法的统计

    -h n

        用于指定每隔几行就输出列头,如果不指定,默认是只在第一行出现列头。

    -JjavaOption

        用于将给定的javaOption传给java应用程序加载器,例如,“-J-Xms48m”将把启动内存设置为48M。如果想查看可以传递哪些选项到应用程序加载器中,可以相看如下的文档:

        Linux and Solaris:http://docs.oracle.com/javase/1.5.0/docs/tooldocs/solaris/java.html

        Windows: http://docs.oracle.com/javase/1.5.0/docs/tooldocs/windows/java.html

    -t n

        用于在输出内容的第一列显示时间戳,这个时间戳代表的时JVM开始启动到现在的时间(注:在IBM JDK5中是没有这个选项的)。

 

    vmid  - VM的进程号,即当前运行的java进程号。

    还有两个关于显示频率的选项:

    interval–间隔时间,单位可以是秒或者毫秒,通过指定s或ms确定,默认单位为毫秒。

    count-打印次数,如果缺省则打印无数次。

3、不同的统计维度(statOption)及输出说明

    -class

类加载情况的统计
列名说明
Loaded 加载了的类的数量
Bytes 加载了的类的大小,单为Kb
Unloaded 卸载了的类的数量
Bytes 卸载了的类的大小,单为Kb
Time 花在类的加载及卸载的时间

     -compiler

HotSpot中即时编译器编译情况的统计
列名说明
Compiled 编译任务执行的次数
Failed 编译任务执行失败的次数
Invalid 编译任务非法执行的次数
Time 执行编译花费的时间
FailedType 最后一次编译失败的编译类型
FailedMethod 最后一次编译失败的类名及方法名

     -gc

JVM中堆的垃圾收集情况的统计
列名说明
S0C 新生代中Survivor space中S0当前容量的大小(KB)
S1C 新生代中Survivor space中S1当前容量的大小(KB)
S0U 新生代中Survivor space中S0容量使用的大小(KB)
S1U 新生代中Survivor space中S1容量使用的大小(KB)
EC Eden space当前容量的大小(KB)
EU Eden space容量使用的大小(KB)
OC Old space当前容量的大小(KB)
OU Old space使用容量的大小(KB)
PC Permanent space当前容量的大小(KB)
PU Permanent space使用容量的大小(KB)
YGC 从应用程序启动到采样时发生 Young GC 的次数
YGCT 从应用程序启动到采样时 Young GC 所用的时间(秒)
FGC 从应用程序启动到采样时发生 Full GC 的次数
FGCT 从应用程序启动到采样时 Full GC 所用的时间(秒)
GCT T从应用程序启动到采样时用于垃圾回收的总时间(单位秒),它的值等于YGC+FGC

    -gccapacity

新生代、老生代及持久代的存储容量情况
列名说明
NGCMN 新生代的最小容量大小(KB)
NGCMX 新生代的最大容量大小(KB)
NGC 当前新生代的容量大小(KB)
S0C 当前新生代中survivor space 0的容量大小(KB)
S1C 当前新生代中survivor space 1的容量大小(KB)
EC Eden space当前容量的大小(KB)
OGCMN 老生代的最小容量大小(KB)
OGCMX 老生代的最大容量大小(KB)
OGC 当前老生代的容量大小(KB)
OC 当前老生代的空间容量大小(KB)
PGCMN 持久代的最小容量大小(KB)
PGCMX 持久代的最大容量大小(KB)
PGC 当前持久代的容量大小(KB)
PC 当前持久代的空间容量大小(KB)
YGC 从应用程序启动到采样时发生 Young GC 的次数
FGC 从应用程序启动到采样时发生 Full GC 的次数

    -gccause

     这个选项用于查看垃圾收集的统计情况(这个和-gcutil选项一样),如果有发生垃圾收集,它还会显示最后一次及当前正在发生垃圾收集的原因,它比-gcutil会多出最后一次垃圾收集原因以及当前正在发生的垃圾收集的原因。

用于查看垃圾收集的统计情况,包括最近发生垃圾的原因
列名说明
LGCC 最后一次垃圾收集的原因,可能为“unknown GCCause”、“System.gc()”等
GCC 当前垃圾收集的原因

    -gcnew

新生代垃圾收集的情况
列名说明
S0C 当前新生代中survivor space 0的容量大小(KB)
S1C 当前新生代中survivor space 1的容量大小(KB)
S0U S0已经使用的大小(KB)
S1U S1已经使用的大小(KB)
TT Tenuring threshold,要了解这个参数,我们需要了解一点Java内存对象的结构,在Sun JVM中,(除了数组之外的)对象都有两个机器字(words)的头部。第一个字中包含这个对象的标示哈希码以及其他一些类似锁状态和等标识信息,第二个字中包含一个指向对象的类的引用,其中第二个字节就会被垃圾收集算法使用到。
在新生代中做垃圾收集的时候,每次复制一个对象后,将增加这个对象的收集计数,当一个对象在新生代中被复制了一定次数后,该算法即判定该对象是长周期的对象,把他移动到老生代,这个阈值叫着tenuring threshold。这个阈值用于表示某个/些在执行批定次数youngGC后还活着的对象,即使此时新生的的Survior没有满,也同样被认为是长周期对象,将会被移到老生代中。
MTT Maximum tenuring threshold,用于表示TT的最大值。
DSS Desired survivor size (KB).可以参与这里:http://blog.csdn.net/yangjun2/article/details/6542357
EC Eden space当前容量的大小(KB)
EU Eden space已经使用的大小(KB)
YGC 从应用程序启动到采样时发生 Young GC 的次数
YGCT 从应用程序启动到采样时 Young GC 所用的时间(单位秒)

    -gcnewcapacity

新生代的存储容量情况
列名说明
NGCMN           新生代的最小容量大小(KB)
NGCMX     新生代的最大容量大小(KB)
NGC     当前新生代的容量大小(KB)
S0CMX 新生代中SO的最大容量大小(KB)
S0C 当前新生代中SO的容量大小(KB)
S1CMX 新生代中S1的最大容量大小(KB)
S1C 当前新生代中S1的容量大小(KB)
ECMX 新生代中Eden的最大容量大小(KB)
EC 当前新生代中Eden的容量大小(KB)
YGC 从应用程序启动到采样时发生 Young GC 的次数
FGC 从应用程序启动到采样时发生 Full GC 的次数

    -gcold

老生代及持久代发生GC的情况
列名说明
PC 当前持久代容量的大小(KB)
PU 持久代使用容量的大小(KB)
OC 当前老年代容量的大小(KB)
OU 老年代使用容量的大小(KB)
YGC 从应用程序启动到采样时发生 Young GC 的次数
FGC 从应用程序启动到采样时发生 Full GC 的次数
FGCT 从应用程序启动到采样时 Full GC 所用的时间(单位秒)
GCT 从应用程序启动到采样时用于垃圾回收的总时间(单位秒),它的值等于YGC+FGC

    -gcoldcapacity

老生代的存储容量情况
列名说明
OGCMN 老生代的最小容量大小(KB)
OGCMX 老生代的最大容量大小(KB)
OGC 当前老生代的容量大小(KB)
OC 当前新生代的空间容量大小(KB)
YGC 从应用程序启动到采样时发生 Young GC 的次数
FGC 从应用程序启动到采样时发生 Full GC 的次数
FGCT 从应用程序启动到采样时 Full GC 所用的时间(单位秒)
GCT 从应用程序启动到采样时用于垃圾回收的总时间(单位秒),它的值等于YGC+FGC

    -gcpermcapacity

    从应用程序启动到采样时发生 Full GC 的次数

持久代的存储容量情况
列名说明
PGCMN 持久代的最小容量大小(KB)
PGCMX 持久代的最大容量大小(KB)
PGC 当前持久代的容量大小(KB)
PC 当前持久代的空间容量大小(KB)
YGC 从应用程序启动到采样时发生 Young GC 的次数
FGC
FGCT 从应用程序启动到采样时 Full GC 所用的时间(单位秒)
GCT 从应用程序启动到采样时用于垃圾回收的总时间(单位秒),它的值等于YGC+FGC

    -gcutil

新生代、老生代及持代垃圾收集的情况
列名说明
S0 Heap上的 Survivor space 0 区已使用空间的百分比
S1 Heap上的 Survivor space 1 区已使用空间的百分比
E Heap上的 Eden space 区已使用空间的百分比
O Heap上的 Old space 区已使用空间的百分比
P Perm space 区已使用空间的百分比
YGC 从应用程序启动到采样时发生 Young GC 的次数
YGCT 从应用程序启动到采样时 Young GC 所用的时间(单位秒)
FGC 从应用程序启动到采样时发生 Full GC 的次数
FGCT 从应用程序启动到采样时 Full GC 所用的时间(单位秒)
GCT 从应用程序启动到采样时用于垃圾回收的总时间(单位秒),它的值等于YGC+FGC

    -printcompilation

HotSpot编译方法的统计
列名说明
Compiled 编译任务执行的次数
Size 方法的字节码所占的字节数
Type 编译类型
Method 指定确定被编译方法的类名及方法名,类名中使名“/”而不是“.”做为命名分隔符,方法名是被指定的类中的方法,这两个字段的格式是由HotSpot中的“-XX:+PrintComplation”选项确定的。



4、使用示例

示例1)、

示例2):

 

图中同时打印了young gc和full gc的总次数、总耗时。而,每次young gc消耗的时间,可以用相间隔的两行YGCT相减得到。每次full gc消耗的时间,可以用相隔的两行FGCT相减得到。例如红框中表示的第一行、第二行之间发生了1次young gc,消耗的时间为0.252-0.252=0.0秒。

常驻内存区(P)的使用率,始终停留在64.21%左右,说明常驻内存没有突变,比较正常。如果young gc和full gc能够正常发生,而且都能有效回收内存,常驻内存区变化不明显,则说明java内存释放情况正常,垃圾回收及时,java内存泄露的几率就会大大降低。但也不能说明一定没有内存泄露。

示例3)、

    以上,介绍了Jstat按百分比查看gc情况的功能。其实,它还有功能,例如加载类信息统计功能、内存池信息统计功能等,那些是以绝对值的形式打印出来的,比较少用,在此就不做介绍。

示例4)、jstat -class pid:显示加载class的数量,及所占空间等信息。

 示例5)、jstat -compiler pid:显示VM实时编译的数量等信息。

 

示例6)、查看远程服务器上的GC情况。

    这个需要先在远程服务器上面开启jstatd服务,可以选看这里如何开启jstatd服务,http://blog.csdn.net/fenglibing/article/details/17323515

    下面是一个执行示例:

C:\Documents and Settings\Administrator>jstat -gcutil 18272@the_ip:2021/jstatdName 1000

  S0     S1     E      O      P     YGC     YGCT    FGC    FGCT     GCT
  0.00   0.00   8.00   0.00  24.36      0    0.000     0    0.000    0.000
  0.00   0.00   8.00   0.00  24.36      0    0.000     0    0.000    0.000
  0.00   0.00   8.00   0.00  24.36      0    0.000     0    0.000    0.000
  0.00   0.00   8.00   0.00  24.36      0    0.000     0    0.000    0.000
  0.00   0.00   8.00   0.00  24.36      0    0.000     0    0.000    0.000
  0.00   0.00   8.00   0.00  24.36      0    0.000     0    0.000    0.000

 

 

 

===================== jmap ==============================

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=<filename> 使用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 ~]$ jmap -histo 4939

[输出较多这里不贴了]

2)、[fenglb@ccbu-156-5 ~]$ jmap -dump:format=b,file=test.bin 4939

Dumping heap to /home/fenglb/test.bin ...

Heap dump file created

 

 

 

 

 ===================== jinfo ==============================

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

 

 

 ===================== jconsole =============================

jconsole:一个java GUI监视工具,可以以图表化的形式显示各种数据。并可通过远程连接监视远程的服务器VM。用java写的GUI程序,用来监控VM,并可监控远程的VM,非常易用,而且功能非常强。命令行里打 jconsole,选则进程就可以了。

需要注意的就是在运行jconsole之前,必须要先设置环境变量DISPLAY,否则会报错误,Linux下设置环境变量如下:

export DISPLAY=:0.0

 [root@localhost bin]# jconsole

上两个图看一下:

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

 

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

 

 

 ===================== jvisualvm =======================

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

 

 

 

 ===================== jhat ====================== 

jhat命令 -- Java Head Analyse Tool 
用途:是用来分析java堆的命令,可以将堆中的对象以html的形式显示出来,包括对象的数量,大小等等,并支持对象查询语言
第一步:导出堆
 
第二步:分析堆文件
 
第三步:查看html

有时你dump出来的堆很大,在启动时会报堆空间不足的错误,可以使用如下参数:
jhat -J-Xmx512m <heap dump file>

对于jhat启动后显示的html页面中功能:
(1)显示出堆中所包含的所有的类

(2)从根集能引用到的对象

(3)显示平台包括的所有类的实例数量

(4)堆实例的分布表

(5)执行对象查询语句

 

 

 

 

===================== jstatd=========================

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全部的访问权限:    

[plain] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. grant codebase "file:${java.home}/../lib/tools.jar" {  
  2.    permission java.security.AllPermission;  
  3. };  

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

[plain] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. jinfo ${PID}|grep java.home  

 

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

[plain] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. System.out.println(System.getProperty("java.home"))  

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

[plain] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. jstatd -J-Djava.security.policy=jstatd.all.policy  

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

 

4、示例

4.1、使用内部RMI注册中心

    下面这个示例演示了通过内部RMI注册中心启动jstatd,这个示例假设没有其它的服务绑定到默认的RMI注册中心端口(默认端口是1099)。

[plain] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. 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注册中心:

[plain] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. rmiregistry&jstatd -J-Djava.security.policy=all.policy  

    这个示例演示了使用一个外部的RMI注册中心来启动jstatd,此注册中心的端口为2020:

[plain] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. rmiregistry 2020&jstatd -J-Djava.security.policy=all.policy -p 2020  

    这个示例演示了使用一个外部的RMI注册中心来启动jstatd,此注册中心的端口为2020,并且绑定到RMI注册中心的名为AlternateJstatdServerName:

[plain] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. rmiregistry 2020&jstatd -J-Djava.security.policy=all.policy -p 2020 -n AlternateJstatdServerName  

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

 

4.3、禁止内部RMI注册中心的创建

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

[plain] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. jstatd -J-Djava.security.policy=all.policy -nr  

 

 

4.4、开启RMI日记记录

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

[plain] view plaincopy在CODE上查看代码片派生到我的代码片
 
    1. jstatd -J-Djava.security.policy=all.policy -J-Djava.rmi.server.logCalls=true  

 

 

 ===================== MAT ==========================

 

1、MAT是什么?

    MAT(Memory Analyzer Tool),一个基于Eclipse的内存分析工具,是一个快速、功能丰富的JAVA heap分析工具,它可以帮助我们查找内存泄漏和减少内存消耗。使用内存分析工具从众多的对象中进行分析,快速的计算出在内存中对象的占用大小,看看是谁阻止了垃圾收集器的回收工作,并可以通过报表直观的查看到可能造成这种结果的对象。

    

2.为什么使用MAT?
    当服务器应用占用了过多内存的时候,会遇到OutOfMemoryError。如何快速定位问题呢?Eclipse MAT的出现使这个问题变得非常简单。它能够离线分析dump的文件数据。
    Eclipse MAT是SAP公司贡献的一个工具,可以在Eclipse网站下载到它,完全免费的。它可比Sun提供的内存镜像分析工具jhat要强太多了。
3.
首页:http://www.eclipse.org/mat/ 
插件更新地址:
http://download.eclipse.org/mat/1.0/update-site/

先调用jdk的工具得到heap使用情况

我安装的是jdk1.6

C:/>java -version

java version "1.6.0_11"

Java(TM) SE Runtime Environment (build 1.6.0_11-b03)

Java HotSpot(TM) Client VM (build 11.0-b16, mixed mode, sharing)

调用jdk工具jps查看当前的java进程

C:/>jps

3504 Jps

3676 Bootstrap

3496 org.eclipse.equinox.launcher_1.0.201.R35x_v20090715.jar

调用jmap工具得到信息

C:/>jmap -dump:format=b,file=heap.bin 3676

Dumping heap to C:/heap.bin ...

Heap dump file created

这时,我们的C盘根目录,就生成了heap.bin文件,用eclipse的file---->open打开这个文件,首先是一个启动图:

这里可以选择查看

1、内存泄露报表,自动检查可能存在内存泄露的对象,通过报表展示存活的对象以及为什么他们没有被垃圾收集;

2、对象报表,对可颖对象的分析,如字符串是否定义重了,空的collection、finalizer以及弱引用等。

我这里选择的是查看内存报表,以下是截的简略图:

 

posted on 2014-04-11 13:43  5彩石头  阅读(366)  评论(0编辑  收藏  举报

导航