如何监视通过 JNI 从 Java 调用的本机 C DLL 正在使用的内存?使用标准 Java 监视工具和选项,我可以看到 Java 内存空间,但我无法查看 C DLL 使用的任何内存。Java 正在使用 ~70MB,但任务管理器中的任务显示 200Mb+,如果可能的话,我想看看额外的 130MB 中有什么。
4 回答
您可以使用性能监视器中的计数器监视本机堆。(perfmon32) 但是它不会在每个 DLL 的基础上为您分解它,甚至 jvm.dll 也会包含在此处。
大多数分析工具都可以附加到进程并捕获和跟踪内存分配和释放。这使他们能够推测泄漏的位置。我最近尝试追踪从 Java 调用的本机代码中的内存泄漏时发现的一个非常好的方法是Memory Validator
您是否尝试过使用Process Viewer进行更深入的挖掘。
如果您有 DLL 的源代码,您可以使用调试库和可能的内存分配跟踪器重新构建 - 并使用可视 C++ 调试器进行调试(您需要告诉它使用 java 应用程序)。
如果您没有源 - 那么选项是有限的。
我相信即使在 C DLL 中这样做也不会很容易。
据我了解,标准 Java 监控工具通过查询虚拟机来收集信息,因此即使该内存在同一个进程中,除非虚拟机知道如何检查您的动态链接库,否则它将无法看到任何内容. 我相信您需要使用外部工具或对 DLL 进行一些大规模修改才能跟踪其内存使用情况。
好吧,由于 DLL 并不是 Java 堆的一部分,我认为最准确的阅读方法是编写一个小型分析程序(小型 Java/JNI 程序或 C++/C# 等)来导入和使用DLL 以与您的应用程序类似的方式进行,并且不执行任何其他操作 - 只需像您一样使用 DLL - 此分析应用程序的结果内存配置文件应该很好地近似于 DLL 的内存配置文件。
您还应该测试是否存在 DLL 的静态或动态内存形状 - 在加载 DLL 之前和之后直接进行内存测量,以查看是否存在约 130MB 的一次性命中,或者内存是否缓慢上升时间。
在 Solaris / Linux 上,我听说 Sun Studio 收集器 / 分析器是一个很好的工具,但是你被困在 DLL 领域(或者说是 DLL 地狱)