我必须评估从正在运行的java程序的内存中提取一些对象(例如java.security.PrivateKey
)是多么困难。
我不太喜欢这个低级内存的东西,所以我从小C程序开始,熟悉gdb
, /proc/<pid>/maps
, /proc/<pid>/mem
和一个脚本 ,内存区域。
但是,切换到java时,事情会改变。 由于垃圾收集,内存分配和pipe理与java非常不同。 在C程序中,我会看一个堆栈地址,并确定它包含了我想要提取的variables。
所以我的问题是:
String
的ID)? java.security.PrivateKey
? 假设JMX被closures。
谢谢你的帮助
这比你想象的更容易:)
HotSpot可维护性代理做到了这一点。 它可以打开核心转储或使用ptrace附加到实时Java进程,然后提取JVM结构和所有Java对象的布局。 目标JVM不需要合作。 即使JMX和Attach机制被禁用,这也可以工作。
以下是如何检查远程JVM中给定类的实例的示例 。
sa-jdi.jar
必须位于类路径中才能使用可维护性代理。
最后是最简单的解决方案。 运行jmap -F -dump:format=b,file=heap.bin PID
注意-F
参数 – 强制jmap
使用Serviceability Agent进行堆转储。
PS这里是SA 的来源 ,如果你想知道它是如何工作的。