志在指尖
用双手敲打未来

使用JDK工具进行Java服务器应用程序故障排除

最近又学到了很多新知识,感谢优锐课老师细致地解说,这篇博客记载下自己所学所想。
1.介绍
Java国际中,咱们大多数人习惯于在Java应用程序开发的一切阶段运用GUI东西:编写代码,对其进行调试和剖析。咱们一般更喜欢在开发环境中设置服务器环境,并测验运用熟悉的东西在本地重现问题。不幸的是,由于各种原因,一般不或许在本地重现一些问题。例如,你或许无权拜访服务器应用程序处理的真实客户端数据。
在这种状况下,你需求在服务器盒上长途对应用程序进行毛病扫除。你应该记住,你无法运用裸露的JRE来正确地对应用程序进行毛病扫除:它包括一切毛病扫除功用,可是实际上无法拜访它。成果,你需求在同一盒子上运用JDK或某些第三方东西。本文将介绍JDK东西,因为与许多组织中需求安全审核的任何第三方东西相比,你或许被答应在生产环境中运用它。
一般,仅需将JDK发行包解压缩到你的包装盒中就足够了——你不需求出于毛病扫除的意图而正确装置它(实际上,在很多状况下不希望正确装置)。关于根据JMX的功用,你实际上能够装置任何Java7/8JDK,可是某些东西无法识别将来的JDK,因而我主张你装置最新的Java7/8JDK或与服务器JRE完全匹配的内部版别-它答应你会为当时没有拜访安全点的应用程序转储应用程序堆(某些处于闲暇模式的应用程序是“无安全点”应用程序的简略示例)。Java
2.毛病扫除方案
2.1.获取正在运转的JVM的列表
为了开端作业,你几乎总是需求获取正在运转的JVM,它们的进程ID和指令行参数的列表。有时或许就足够了:你或许会发现同一应用程序的第二个实例一起履行相同的作业(并损坏输出文件/从头翻开套接字/履行其他一些愚蠢的操作)。
只需运转jcmd而无需任何参数。它将向你显现正在运转的JVM的列表:
13824org.jetbrains.idea.maven.server.RemoteMavenServer221963780sun.tools.jcmd.JCmd
现在,你能够通过运转jcmdhelp指令来查看哪些确诊指令可用于给定的JVM。这是VisualVM的示例输出:
1>jcmd3036help233036:4Thefollowingcommandsareavailable:5JFR.stop6JFR.start7JFR.dump8JFR.check9VM.native_memory10VM.check_commercial_features11VM.unlock_commercial_features12ManagementAgent.stop13ManagementAgent.start_local14ManagementAgent.start15GC.rotate_log16Thread.print17GC.class_stats18GC.class_histogram19GC.heap_dump20GC.run_finalization21GC.run22VM.uptime23VM.flags24VM.system_properties25VM.command_line26VM.version27help
键入jcmd来运转确诊指令或得到一条错误消息,问询指令参数:
1>jcmd3036GC.heap_dump233036:4java.lang.IllegalArgumentException:Theargument’filename’ismandatory.
你能够运用以下指令获取有关确诊指令参数的更多信息:jcmd帮助。例如,这是GC.heap_dump指令的输出:
1>jcmd3036helpGC.heap_dump233036:4GC.heap_dump5GenerateaHPROFformatdumpoftheJavaheap.67Impact:High:DependsonJavaheapsizeandcontent.RequestafullGCunlessthe’-all’optionisspecified.89Permission:java.lang.management.ManagementPermission(monitor)1011Syntax:GC.heap_dump[options]1213Arguments:14filename:Nameofthedumpfile(STRING,nodefaultvalue)1516Options:(optionsmustbespecifiedusingtheor=syntax)17-all:[optional]Dumpallobjects,includingunreachableobjects(BOOLEAN,false)
2.2.进行堆转储
jcmd为你供给了一个方便的界面,用于以HPROF格局进行堆转储。只需运转jcmdGC.heap_dump。请留意,文件名是相关于正在运转的JVM当时目录而不是当时目录的,因而你或许需求指定完好路径。最好运用.hprof扩展名作为转储文件名。
线程转储完成后,你能够将文件仿制到自己的盒子中,然后在VisualVM(它是JDK的一部分)中翻开它,并运用其堆walker和查询语言功用,或将其加载到JavaMissionControl的JOverflow插件中并对其进行剖析各种内存问题。
留意1:当然,还有许多其他东西能够处理hprof文件:NetBeans,EclipseMemoryAnalyzer,YourKit等。将.hprof文件下载到框中后,请运用你喜欢的东西。
留意2:你也能够运用jmap东西进行堆转储:jmap-dump:live,file=。问题在于它被正式证明为不受支持。咱们中的许多人都认为JDK中不受支持的内容将永远存在,但现实证明状况不再如此:JEP240,JEP241
2.3.剖析类直方图
假如你正在寻找内存走漏,一般只对堆中某些特定类型的活动目标感兴趣。例如,你或许知道一次只能拥有一个特定类型的目标(应用程序中的某种首要作业类)。在旧的一代中或许还存在一个或多个相同类的实例,到目前为止,这些实例没有进行废物回收,可是不应从应用程序根目录拜访它们。
要打印类直方图,请运转以下两个指令之一(两个指令均打印活动目标的数量):
1jcmdGC.class_histogram2jmap-histo:live
以下是示例输出的前几行:
1num#instances#bytesclassname2———————————————-31:59235976952[I42:500344127704[C53:494651187160java.lang.String64:1881069496[J75:39851067240[Ljava.util.HashMap$Node;86:8756982872java.lang.Class97:2855835792[B108:23570754240java.util.HashMap$Node119:13964671440[Ljava.lang.Object;1210:9642308544java.util.Hashtable$Entry1311:4453213744java.util.HashMap
请留意,以字节为单位的已占用巨细是一个较浅的巨细–它不包括任何子目标。很简单从char[](类名=[C]和Stringstats)中留意到这一现实–虽然实例数是相似的(虽然char[]-s总是比String多,可是char[]-的巨细s显着更大,假如String的巨细包括基础char[]的巨细,则状况并非如此。
现在,你能够grep/搜索你感兴趣的类名称,并查看活动实例的数量。假如看到的实例超出预期,请进行堆转储并在任何堆遍历器中对其进行剖析(请拜见上文)。
2.4.进行线程转储
有时,你的应用程序或许会报告为“notdoinganything/gotstuck”。有很多种“stuck”的状况——死锁,高资源争用或仅是O(N10)算法来处理数百万用户的请求,在一切这些状况下,你应该知道你的应用程序线程正在履行什么以及锁将履行什么操作他们持有。
有两种类型的锁:根据同步关键字和Object.wait/notifyAll办法的原始锁,以及Java5中引进的java.util.concurrent锁。它们之间的首要区别是前者绑定到你输入的堆栈结构上同步部分,并且在线程转储中始终可用。另一方面,后者(java.util.concurrent)不受堆栈结构约束——你能够运用一种办法输入锁,然后将其保留在另一种办法中。成果,一段时间以来,它们根本没有在线程转储中打印,即便现在它们仍然是一个选项。可是,你需求在线程转储中一起运用两种锁,以正确查询线程问题。
有3种打印应用程序线程转储的办法。你能够在Linux上运转kill-3。或许,你能够在任何平台上运转以下指令之一:
1jstack2jcmdThread.print
2.5.运转JavaFlightRecorder
到目前为止,本文中说到的一切东西仅应用于快速查询。为了进行更深入的剖析,我主张运用内置的JavaFlightRecorder。
运转JFR是一个三步过程:
你需求创立一个包括所需设置的JFR模板文件。为此,请运转jmc并转到“窗口”->“飞翔记载模板管理器”菜单。配置文件准备就绪后,将其导出到文件中,然后将其发送到你正在运用的框中。
JFR需求JDK商业许可证。现在,你需求在所需的JVM上解锁商业功用:
1jcmdVM.unlock_commercial_features
之后,你能够启动JFR。这是指令行示例:
1jcmdJFR.startname=testduration=60ssettings=template.jfcfilename=output.jfr
此指令立即运转JFR(未设置delay特点),并运用template.jfc模板文件中的设置并将成果写入output.jfr(在两个文件中都运用绝对路径),收集JVM信息60秒钟。
录制完成后,你能够将.jfr文件仿制到笔记本电脑并在jmcGUI中对其进行剖析。它包括几乎一切你需求对JVM进行毛病扫除的信息,除了完好堆转储,你能够单独创立并仿制到你的机器中。

未经允许不得转载:IT技术网站 » 使用JDK工具进行Java服务器应用程序故障排除
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!

 

志在指尖 用双手敲打未来

登录/注册IT技术大全

热门IT技术

C#基础入门   SQL server数据库   系统SEO学习教程   WordPress小技巧   WordPress插件   脚本与源码下载