到目前为止,我已经了解了分别使用jstack
和jmap
生成线程转储和堆转储。
但是,jstack
线程转储仅包含描述每个线程上的堆栈的文本。使用Java VisualVM打开堆转储(.hprof文件)只显示堆中分配的对象。
我真正想要的是能够看到堆栈,切换到特定的堆栈帧,以及观察局部变量。这种事后调试可以通过WinDbg,gdb和核心文件(用于本机C ++程序)等工具正常完成。
我想知道Java中是否存在这样的'核心'文件(允许我在非实时环境中调试)?
答案 0 :(得分:5)
Java确实如此。如果您使用的是IBM VM,请使用com.ibm.jvm.Dump.SystemDump()
以编程方式生成转储。这可以使用调试器进行调试。我相信“杀死”你的Java进程也应该生成一个系统转储。对于Unix使用kill -4 pid
,其中pid是进程ID,如果有1个VM实例正在运行,可以通过键入top | grep java
来查询。
您还可以在java命令行中添加-Xdump:system
或-Xdump:heap
等来过滤事件并在VM Stop(-Xdump:system:events=vmstop
)等特定事件上生成转储,完整垃圾收集({{请注意,根据您的堆大小,在完整GC上生成转储可能不是一个好主意(例如,如果堆从40M增加到大约60M,则可能会创建50个转储,持续20秒因此你可以添加一个像-Xdump:system:events=fullgc
这样的计数器,它可以在第50到第55个完全垃圾收集之间生成5个核心。
答案 1 :(得分:2)
我在Sun forum和SO discussion中找到了相关信息:我没有太多运气,但它可能适用于您的情况。
注意:提到的一些工具是Java工具,但不受支持,并且在Windows版本的JDK上不可用。
答案 2 :(得分:1)
我认为标准Java中不存在这种转储机制。
答案 3 :(得分:1)
某些操作系统(例如Linux上的Solaris mdb或gdb)支持在转储文件上使用普通的本机调试器,并对显示Java堆栈帧提供了一些特殊支持。但这非常硬核,可能不是您想要的,因为它与Java调试器没有很好的集成。