如何确定当前进程中运行的 JVM 的 Java 堆在内存中的地址?也就是说,使用 Java、C 或其他调用获取一个 void* 指针或等效于 JVM 为堆分配的连续内存区域?
Matlab 在其进程中嵌入了一个 JVM。 JVM 分配的内存不可用于 Matlab 数组,其中,堆很重要,因为它占用了一大块连续的内存并且从不收缩,而 Matlab 的数组也需要连续的内存。如果在扩展期间重新分配堆,可能会导致碎片。
我想检测我的进程来检查 Java 堆和 Matlab 的内存 View 之间的交互,并找出它何时因调整大小而移动,最好是在进程内。这需要堆的地址。从 java.lang.Runtime 很容易找到堆大小,但不是它在内存中的地址。如何做到这一点?
我在 Windows XP 和 Server 2003 上的 Matlab R2008b 进程中运行 Sun 的 JRE 1.6.0_04。我意识到这可能需要一种特定于供应商的技术。该进程运行我们编写的代码,因此我们可以使用自定义 Java、Matlab、JNI 和 C/C++ 代码。 JVM 中的 Java 方法调用或支持的 Hook 比低级黑客更受欢迎。
编辑:这样做的目的是检查 JVM 的 GC 和 Matlab 的 GC 之间的交互。我不需要查看 Java 堆,也不会从该内存中读取任何内容;我只是想看看它在整个虚拟内存空间的上下文中的位置,Matlab 的 GC 也在尝试将数据放入其中。
最佳答案
获取 JVM 实际堆地址的一种快速但肮脏的方法是跳转到 WinDbg,附加到 JVM 并发出单个 !address 命令。 0x2 附近的某个地方?????? (它在 jvm 版本之间有所不同,但对于该版本保持静态)将是一个标记为 PAGE_EXECUTE_READWRITE 的大型 VAD,这是进程内存中的 JVM 堆。
为了确认,您可以在 kernel32!VirtualAlloc 上设置一个断点,并且在模块 JVM.DLL 中进行 JVM 初始化时,您将命中对 VirtualAlloc 的调用,向您显示 jvm 分配它的堆。如果查看此调用周围的代码,您可以看到地址是如何计算的。
关于java - 如何获取Java堆的内存地址?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/859604/