是否可以从堆转储实例化 jvm?
每个人都知道堆转储可以从正在运行的 JVM 中获取。另一种方式可能吗?我们可以使用堆转储启动 JVM 吗?
这个问题我已经考虑了很长时间了。如果可能的话,它将解决很多时间,并使支持工程师的思考变得容易。如果我们必须重现客户面临的一些罕见问题,它会很有帮助。[想象一下,底层硬件和 Java 运行时是相同的,并且所有支持文件也都存在于文件系统中的相应位置]。
添加说明:这样做的目的不是在OOM发生时,而是在JVM启动后的任何给定点。
每个人都知道堆转储可以从正在运行的 JVM 中获取。另一种方式可能吗?我们可以使用堆转储启动 JVM 吗?
这个问题我已经考虑了很长时间了。如果可能的话,它将解决很多时间,并使支持工程师的思考变得容易。如果我们必须重现客户面临的一些罕见问题,它会很有帮助。[想象一下,底层硬件和 Java 运行时是相同的,并且所有支持文件也都存在于文件系统中的相应位置]。
添加说明:这样做的目的不是在OOM发生时,而是在JVM启动后的任何给定点。
不,你不能。您将需要每个打开的文件中的当前位置之类的内容。这会影响在简单的顺序读取中返回的数据。还原程序需要打开每个文件并将其放到正确的位置。对于不可寻道的流,这可能是不可能的。
特定于程序的序列化是一个更可行的路径,然后从那里安装程序。
此外,由于堆转储通常来自 OutOfMemory situtaions,因此从相同位置重新创建 JVM 会再次抛出 OutOfMemoryException。如果要在两者之间进行堆转储,则序列化对象并在启动 jvm 时还原它们。
(内容抄自这个问题的评论,作者almas-shaikh和patricia-shanahan)
要从正在运行的 JVM 创建堆转储,您还可以使用 jhat 或 jcmd(使用 GC.heap_dump 命令),两者都存在于 JDK/bin 文件夹中。MAT 是分析转储内容的一种方法。Java Mission Control有一个名为JOverflow的工具,可以分析堆转储,但只是为了查看内存浪费模式。
我从来没有听说过任何方法可以从图像中重新启动JVM,堆转储根本不足够,因为它只包含Java对象,而不是编译的代码和其他东西。