JavaDump分析.doc_第1页
JavaDump分析.doc_第2页
JavaDump分析.doc_第3页
JavaDump分析.doc_第4页
JavaDump分析.doc_第5页
已阅读5页,还剩19页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

JavaDump分析一、 Java Dump概述Dump,即“转储”。Java Dump可以保留Java虚拟机的瞬时快照。相比于传统的控制台输出,提供了更多的信息用于分析运行系统状态及错误。可弥补传统在Java平台上分析Bug手段的一些不足。Java Dump分为两种:l 线程Dump:纯文本格式。包含所有线程的运行状态、调用栈、锁信息等。l 堆Dump:二进制格式,需要工具查看。包含了线程Dump的所有信息,此外还包括系统信息、Java虚拟机参数以及堆对象的状态。Java Dump的分析,特别适合于生产环境下,并且针对非功能性的问题,主要为:多线程并发、内存泄漏。二、 制作Dump1. Java虚拟机发行版不同Java虚拟机的Dump规范不完全相同,所以在制作Dump时,需要注意虚拟机发行版。l HotSpot VM:原Sun提供的官方Java虚拟机,支持Linux、Windows、Solaris平台。l OpenJDK:Sun JDK的开源版本,1.6后跟HotSpot差别不太大了。l JRockit:WebLogic使用的Java虚拟机,BEA开发。l IBM J9 VM:IBM开发的Java虚拟机,AIX平台上的唯一实现。2. 原理3. 注意事项1) Java虚拟机发行版使用相同的Java虚拟机发行版。即意味着使用SunJDK的工具,连接SunJRE的应用系统来制作Dump。2) 版本要求l 目标虚拟机必须为1.6或以及的jdk。使用OOM参数制作堆Dump可使用1.5的jdk。(各虚拟机差异较大)l 制作工具需要使用相同发行版的jdk,并且建议1.6以上。3) 堆Dump格式相对纯文本的线程dump而言,堆Dump目前存在多种不同的格式。l HPROF,Sun 的Java虚拟机的堆Dump格式。l PHD,IBM Portable Heap Dump。IBM J9 VM生成的Dump格式。4. 使用虚拟机参数1) 内存溢出时自动堆Dump为虚拟机增加启动参数:-XX:+HeapDumpOnOutOfMemoryError则当虚拟机发生OutOfMemoryError时,自动生成堆Dump。该参数对生产环境是否有用,可保存崩溃的现场,分析内存泄漏等。5. 使用图形工具1) Java VisualVMJava VisualVM是从SunJDK_1.6开始自带的图形化工具,集成了jps、jmap、jstat等多个实用工具。在Windows环境下,推荐使用该工具制作线程Dump及堆Dump。此外,该工具还可做简单的内存分析。Java VisualVM位于JDK的bin目录下,界面如下:窗口左边为本机的Java进程,选择需要制作Dump的Java进程,点击右键选择“线程Dump”或“堆Dump”制作相应的Dump。生成的Dump位于进程节点下,需要选择并另存到文件才能持久化保存。Java VisualVM也支持从远程制作Dump,但由于涉及到较为复杂的权限配置操作,故强烈不推荐使用,在此不详述。建议从本地使用Java VisualVM来连接虚拟机。2) Memory Analyzer (mat)Memory Analyzer是Eclipse基金会开发的Java堆Dump分析工具,也支持制作堆Dump。其界面如下:点击File-Acquire Heap Dump可制作堆Dump。首先需要选择在本机运行的目标Java进程。通过Configure菜单,MAT还可以制作其他格式的堆Dump。3) JProfiler使用JProfiler连接上Java虚拟机后,使用Save HPROF snapshot来制作堆Dump。示例:6. 使用命令行以下介绍针对SunJDK即HotSpotVM。使用命令行制作Dump,建议严格按照以下四步骤。1) 检查Java版本使用java version命令。windows平台示例:C:java -versionjava version 1.6.0_24Java(TM) SE Runtime Environment (build 1.6.0_24-b07)Java HotSpot(TM) 64-Bit Server VM (build 19.1-b02, mixed mode)Linux平台示例,注意bin目录中的Java版本。devlocalhost bin$ java -versionjava version 1.6.0_22OpenJDK Runtime Environment (IcedTea6 1.10.6) (rhel-0.6.el6_2-x86_64)OpenJDK 64-Bit Server VM (build 20.0-b11, mixed mode)devlocalhost bin$ ./java -versionjava version 1.6.0_31Java(TM) SE Runtime Environment (build 1.6.0_31-b04)Java HotSpot(TM) 64-Bit Server VM (build 20.6-b01, mixed mode)2) 查看Java进程的ID使用jps命令,一般带-l参数,或者-v参数。命令格式如下:jpsjps ljps -vLinux平台下有时候也需要使用ps命令,格式如下:ps ef|grep java在Linux平台下的示例如:devlocalhost bin$./jps l1018 beans.Main1223 sun.tools.jps.Jps2316 /home/dev/dna/srvmgr/thr/com.jiuqi.dna.launcher_1.0.0.jar3) jstack制作线程Dumpjstack工具,会将Dump内容输出到指定的文件,格式为:jstack Windows平台示例:C:jstack 2316 c:thread.txtLinux平台示例:devlocalhost bin$ ./jstack 2316 thread.txt4) kill制作线程DumpLinux平台上还可以使用Kill命令制作线程Dump。这里kill -3是向进程发送消息,并不会杀掉进程。该命令将线程Dump的内容输出到标准输出(stdout)。并且相对jstack命令,kill命令会包含进程的内存信息。kill命令的格式如下:kill -3 kill quit 示例如下:devlocalhost bin$ kill -quit 2316devlocalhost bin$ kill -3 2316建议使用-quit参数,以防止手误。5) jmap制作堆Dumpjmap将堆Dump输出到指定的文件,格式为:jmap dump:format=b,file= Windows平台示例:C:jmap -dump:format=b,file=c:heap.hprof 2316Dumping heap to C:heap.hprof .Heap dump file createdLinux平台示例:devlocalhost bin$ ./jmap -dump:format=b,file=heap.hprof 2316Dumping heap to /usr/java/1.6.0_31/bin/heap.hprof .Heap dump file created7. 制作Dump总结图形化命令行线程DumpJava VisualVMjmap命令堆DumpJava VisualVMJstack命令、kill -3命令三、 线程Dump的分析1. 示例一个线程Dump的片段如下:2. 内容线程Dump主要包含以下几个信息:1) 制作时间及jre版本2) 线程运行状态及调用栈主要的部分,包括:线程名称、线程优先级、线程状态以及调用栈。3) 线程锁信息例如:- waiting on (a com.jiuqi.dna.core.impl.WorkingThread)at com.jiuqi.dna.core.impl.WorkingManager.getWorkToDo(WorkingManager.java:322)- locked (a com.jiuqi.dna.core.impl.WorkingThread)指示线程已经锁住了某对象,并且正在等待锁住另一对象。4) 死锁信息在制作线程Dump时,Java虚拟机会侦测死锁。如果发生了直接Java对象上的死锁,则输出该部分。5) 堆内存信息当使用Kill-3命令制作时,会包含该部分。3. 使用范围l 系统无响应时,查看虚拟机运行情况。l 分析是否发生了死锁:Java虚拟机内的;和数据库共同组成的。l 结合代码,分析死锁产生的原因。4. 线程运行状态常见的线程运行状态:l RUNNABLE,正常运行的线程。l BLOCKED,由于无法获取到资源而被阻塞的线程。例如synchronized块。l WAITING,空闲等待的线程,一般是调用了Object.wait()方法。l TIMED_WATING,空闲等待的线程,一般是调用了Object.wait(long)方法。其他5. 监视器监视器是Java虚拟机用于控制对对象的锁并发访问的结构。 监视器:对象锁的访问控制结构。也指对象的锁。 监视器项:线程的代理人。 进入区:表示线程通过synchronized要求获取对象的锁。如果对象未被锁住,则进入拥有者;否则则在进入区等待。一旦对象锁被其他线程释放,立即参与竞争。 拥有者:表示某一线程成功竞争到对象锁。 等待区:表示线程通过对象的wait方法,释放对象的锁,并在等待区等待被唤醒。6. 调用修饰调用修饰表示线程在方法调用时额外的信息。修饰上方的方法。例如以下调用栈:d&a-4050 daemon in Object.wait() java.lang.Thread.State: TIMED_WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on (a WorkingThread) at com.jiuqi.dna.core.impl.WorkingManager.getWorkToDo(WorkingManager.java) - locked (a WorkingThread) at com.jiuqi.dna.core.impl.WorkingThread.run(WorkingThread.java)其中locked修饰方法WorkingManager.getWorkToDo;waiting on修饰方法Object.wait。1) locked调用栈类似:at oracle.jdbc.driver.PhysicalConnection.prepareStatement- locked (a oracle.jdbc.driver.T4CConnection)at oracle.jdbc.driver.PhysicalConnection.prepareStatement- locked (a oracle.jdbc.driver.T4CConnection)at ernal.db.datasource.PooledConnection.prepareStatement该修饰表示:线程通过synchronized关键字,成功获取到了对象的锁,成为监视器的拥有者,在临界区内操作。对象锁是可以线程重入的。2) waiting to lock调用栈类似:at com.jiuqi.dna.core.impl.CacheHolder.isVisibleIn(CacheHolder.java:165)- waiting to lock (a CacheHolder)at com.jiuqi.dna.core.impl.CacheGroup$Index.findHolderat com.jiuqi.dna.core.impl.ContextImpl.findat mon.util.BaseDataCenter.findInfo该修饰表示:线程通过synchronized关键字,没有获取到了对象的锁,线程在监视器的进入区等待。该修饰只在调用栈顶出现,并且线程状态为Blocked。3) waiting on调用栈类似:at java.lang.Object.wait(Native Method)- waiting on (a WorkingThread)at com.jiuqi.dna.core.impl.WorkingManager.getWorkToDo- locked (a WorkingThread)at com.jiuqi.dna.core.impl.WorkingThread.run该修饰表示:线程通过通过synchronized关键字,成功获取到了对象的锁后,调用了wait方法,进去对象的等待区等待。在调用栈顶出现,线程状态为WAITING或TIMED_WATING。对应代码的话,如下:synchronized(thread) / thread的类型是WorkingThread / 同步块操作 try thread.wait(); catch(InterruptException e) /* 中断异常处理 */ 线程应正在wait方法上等待。4) parking to wait for调用栈类似:at sun.misc.Unsafe.park(Native Method)- parking to wait for (a FutureTask$Sync)at java.util.concurrent.locks.LockSupport.park(LockSupport:156).at java.util.concurrent.locks.ReentrantReadWriteLock$WriteLock.lock()park是基本的线程阻塞原语,不通过监视器在对象上阻塞。park是随concurrent包会出现的新的机制,与synchronized体系不同。7. 线程动作描述线程正在执行的动作,线程状态造成的原因。 runnable, in Object.wait(),等待区等待。 waiting for monitor entry,BLOCKED的线程,肯定有问题的。 waiting on condition,一般为系统线程或park的线程。 sleeping,休眠的。8. 工具1) Thread Dump Analyzer(TDA)Windows平台应用。建议使用。l 可直接加载Java虚拟机控制台输出,分析出多个线程Dump。l 方便的查看各线程的运行状态,调用栈等信息。l 查看异常的监视器及相关线程。l 提供过滤器定位指定的线程。2) IBM Thread and Monitor Dump Analyzer for Java(TMDA)基于Java开发,使用jar包运行。也可在IBM Support Assistant中集成。l 无法直接分析控制输出。l 能够分析虚拟机线程的统计信息。l 能够方便查看监视器信息及相关依赖的线程。l 能够比较多个线程Dump的线程信息,及监视器信息。四、 堆Dump的分析1. 内容l 系统属性,JVM参数。l 线程Dumpl 堆内存状态所有对象的属性。2. 使用范围1) 内存泄漏OutOfMemoryError以及GC Overhead Limit异常。2) 查看对象属性l 调用栈信息不足以分析问题。l 验证内部对象的数据正确性。3. Java内存模型与GCJava虚拟机内存结构。JVM内存分为:YongGen,OldGen,PermGen三部分。YongGen用于较新的对象,分为:Eden、Survior0、Survior1,有时也称作为:New、From、To。其中新分配的对象存储在Eden。在经过垃圾回收残留的对象,会被移动到Survior区。在经过若干GC后,会进一步的被移动到OldGen。PermGen用于存储Class等信息,不会被GC。内存分配上:一般PermGen占64MB-256MB;YongGen占1/4的JVM内存;剩余的内存分配给OldGen。针对YongGen的垃圾回收为“GC”,时间级别为毫秒;针对OldGen的垃圾回收为“Full GC”,时间级别为秒。4. GC Overhead LimitGC Overhead Limit为另外一种内存不足的形式。产生的场景为:虚拟机的内存使用已经几乎饱和。但执行垃圾回收后,只能回收很小部分的内存。在内存被快速分配后,虚拟机不得不继续执行GC。最终导致整个虚拟机的绝大部分时间消耗在GC上。虽然虚拟机不回抛出OOM的错误,但实际上虚拟机已经处于不正常状态。不回抛出异

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论