从正在运行的 JVM 导出数据?
Posted
技术标签:
【中文标题】从正在运行的 JVM 导出数据?【英文标题】:Export data from running JVM? 【发布时间】:2016-05-24 12:27:51 【问题描述】:这可能是一个很长的问题,但我遇到了一个非常复杂的问题,我不确定如何解决它。
长话短说,我们正在运行一个 Java 应用程序,它目前正在使用 JDBC 在启动时从 mysql 数据库中提取数据。
我们经历了一次崩溃,该数据库不再处于活动状态,并且永远丢失了,随之而来的数据也在内部非常有价值。
但是,数据仍存储在将其拉入的运行 JVM 的堆中。
我现在唯一的希望是以某种方式从正在运行的 JVM 中提取数据,在理想情况下,我将能够附加到它并灵活地运行可以访问内部运行类的代码..
所以我今天的问题是:
我的方法合理可行吗? 如果是这样,我如何附加到 JVM 和“注入”代码感谢您的阅读
【问题讨论】:
你知道attach API吗?还有堆转储? 见How to get a thread and heap dump of a Java process on Windows that's not running in a console。 【参考方案1】:在这种情况下,Eclipse Memory Analyzer Tool 可能是一个很好的解决方案。它也适用于堆转储,并向您显示哪些对象占用了内存。 除此之外,它还可以显示对象/内存位置的内容。
我有时发现 MAT 超出了 VisualVM 的功能,但也许像这样的视图可以帮助您找到数据:
(这是一个虚构示例的屏幕截图,我在其中创建了一些自定义对象 为了在堆转储中显示它们的值)
也许您甚至可以将 Eclipse 附加到正在运行的应用程序。有一个技巧,您可以在断点中运行自定义代码。这可能会以某种方式将您的数据转储到磁盘。
【讨论】:
【参考方案2】:看来您要使用的是jmap
命令。 jmap
可用于将正在运行的 JVM 的堆转储到文件中,然后您可以使用 jhat
或 JVisualVM 等工具“离线”分析该文件。
它允许您在不杀死 JVM 和/或向其中注入代码的情况下执行此操作,并且由于堆转储文件是“惰性的”,因此您可以在闲暇时对其进行分析,而不必担心通过进一步探测而损害正在运行的 VM .诚然,我没有广泛使用它,所以我不确定它的功能到底是什么,但理论上,您也许还可以使用 JVisualVM 的 OQL 语言对堆中的数据运行自动化序列并将其转储到文件中你想要的。
例如,请参阅this question 以获取用法示例。
【讨论】:
以上是关于从正在运行的 JVM 导出数据?的主要内容,如果未能解决你的问题,请参考以下文章