3.1参数及调优
1.-XX:-HeapDumpOnOutOfMemoryError:当首次遭遇内存溢出时Dump出此时的堆内存。
2.-XX:HeapDumpPath=./java_pid.hprof:指定Dump堆内存时的路径
3.-Xms10M
4.-Xmx10M
通过jconsole或jvisualvm查看jvm内存情况
通过Eclipse Memory Analysis查看dump出的文件内容。
JDK本身提供了很多方便的JVM性能调优监控工具,除了集成式的VisualVM和jConsole外,还有jps、jstack、jmap、jhat、jstat等小巧的工具。路径在JAVA_HOME/bin下。
3.1.1 jps
Java Virtual Machine Process Status Tool,查看虚拟机上进程状态信息。
jps [-q] [-mlvV] []
-q 只列出JVM进程标识ID
-m 展示传递给main方法的参数,嵌入式JVM输出null
-l 展示主类的全包名或者可运行jar包的全路径名
-v 展示JVM进程的选项参数
-V 同-q选项,只列出JVM进程标识ID
hostid:包含通信协议、主机IP、通信端口等可选信息,是一个如下格式的URI:[protocol:][[//]hostname][:port][/servername]
虚拟机自带的一种堆栈跟踪工具。jstack用于打印出给定的java进程ID或core file或远程调试服务的Java堆栈信息。一般使用情况如下:
1.jps 获取程序pid
2.jstack pid 获取堆栈信息
线程状态如下:
1.NEW,未启动的。不会出现在Dump中。
2.RUNNABLE,在虚拟机内执行的。运行中状态,可能里面还能看到locked字样,表明它获得了某把锁。
3.BLOCKED,受阻塞并等待监视器锁。被某个锁(synchronizers)給block住了。
4.WATING,无限期等待另一个线程执行特定操作。等待某个condition或monitor发生,一般停留在park(), wait(), sleep(),join() 等语句里。
5.TIMED_WATING,有时限的等待另一个线程的特定操作。和WAITING的区别是wait() 等语句加上了时间限制 wait(timeout)。
4.TERMINATED,已退出的。
调用修饰:
表示线程在方法调用时,额外的重要的操作。线程Dump分析的重要信息。修饰上方的方法调用。
1.locked 目标:使用synchronized申请对象锁成功,监视器的拥有者。
2.waiting to lock 目标:使用synchronized申请对象锁未成功,在迚入区等待。
3.waiting on 目标:使用synchronized申请对象锁成功后,释放锁幵在等待区等待。
4.parking to wait for 目标
举例:比如一个死锁程序。
死锁:是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。
比如:AB都要做鸡蛋灌饼,A拿了鸡蛋,B拿了饼,A想要饼,B想要鸡蛋
堆栈信息如下:Found one Java-level deadlock:============================="Thread-1": waiting to lock monitor 0x00007f0134003ae8 (object 0x00000007d6aa2c98, a java.lang.Object), which is held by "Thread-0""Thread-0": waiting to lock monitor 0x00007f0134006168 (object 0x00000007d6aa2ca8, a java.lang.Object), which is held by "Thread-1" Java stack information for the threads listed above:==================================================="Thread-1": at javaCommand.DeadLockclass.run(JStackDemo.java:40) - waiting to lock <0x00000007d6aa2c98> (a java.lang.Object) - locked <0x00000007d6aa2ca8> (a java.lang.Object) at java.lang.Thread.run(Thread.java:745)"Thread-0": at javaCommand.DeadLockclass.run(JStackDemo.java:27) - waiting to lock <0x00000007d6aa2ca8> (a java.lang.Object) - locked <0x00000007d6aa2c98> (a java.lang.Object) at java.lang.Thread.run(Thread.java:745) Found 1 deadlock.
很详细,发现一个死锁
Thread-1在想要执行第40行的时候,当前锁住了资源<0x00000007d6aa2ca8>,但是他在等待资源<0x00000007d6aa2c98>Thread-0在想要执行第27行的时候,当前锁住了资源<0x00000007d6aa2c98>,但是他在等待资源<0x00000007d6aa2ca8> 由于这两个线程都持有资源,并且都需要对方的资源,所以造成了死锁。 原因我们找到了,就可以具体问题具体分析,解决这个死锁了。
对Java应用程序的资源和性能进行实时监控的命令行工具,主要包括GC情况和Heap Size资源使用情况。参数如下:
option 常见的都是使用-gcutil(和gc基本相同,输出主要已使用空间站总空间的百分比)查看gc(监视堆情况)情况,其他可选项见下图。
vmid : VM的进程号,即当前运行的java进程号。
interval : 间隔时间,单位为秒或毫秒
count:打印次数,如果缺省则打印无数次。
获取堆内存快照,但是比较大。通过配置jvm启动参数-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/path,在oom错误时获取自动生成dump文件,也可以通过jmap获取dump文件,然后通过eclipse中安装MAT插件查看分析。