【问题标题】:Not enough memory for JVM heap when calling jni from dynamic library从动态库调用 jni 时 JVM 堆内存不足
【发布时间】:2015-10-23 12:58:25
【问题描述】:

我有一个奇怪的情况:我们有 .dll 库(我们称它为“sdk_wrapper”),它是 Java 类的包装器,它打开 JRE jvm.dll 并使用其他一些 .dll(PKCS11 实现,更具体地说- 但我认为没关系)。

当我直接在我的 c++ 程序中使用 sdk_wrapper(别名“run_dll”)时,一切正常。但是当我将它打包到另一个 .dll 中(准备配置文件、初始化库等)并导出一个与程序“run_dll”相同的函数时,调用它会导致 jvm 初始化错误:Could not reserve enough space for object heap。 JVM.dll 初始化是用-Xmx512m 做的。

你知道发生了什么吗?我读到 JVM 需要连续的部分内存来初始化,但是直接从程序和另一个 dll 调用“sdk_wrapper”有什么区别?它们在同一个地方(我的意思是在同一个目录中)。

【问题讨论】:

    标签: java c++ dll jvm java-native-interface


    【解决方案1】:

    当您将库加载到内存中时,地址空间会出现内存碎片。 Win32 对此尤其不利。

    注意:如果您使用 64 位进程,这不是问题,因为您将拥有大量虚拟内存。

    【讨论】:

    • 好的,那么加载调用java的a.dll和加载调用java的加载a.dll的b.dll有什么区别呢?
    • 您加载的每个 DLL 都会使用一些内存,并且可能会加载到次优位置。 JVM 需要连续的堆内存,这对 Windows 来说是个问题,它往往会分割它的虚拟地址空间。
    • 是的,我明白了 - 但是为什么直接从 .exe 加载 sdk_wrapper 不会导致错误,而从另一个 .dll 加载它会导致错误?
    • @rzysia 你得问微软为什么他们设计操作系统的方式是这样的。但是我怀疑即使他们也不知道,因为当他们实现 64 位时,他们并没有这样做。如果您使用 64 位 JVM 和 DLL,则不会出现此问题。
    • 现在变得更奇怪了——当我使用 jre8 时,它可以工作,但是对于旧的 jre,它会失败。在这种特殊情况下,我不能使用 64 位 .dll,但我可以使用 jre8,所以现在一切正常。无论如何,感谢您的帮助:)
    猜你喜欢
    • 1970-01-01
    • 2014-02-11
    • 1970-01-01
    • 2020-12-09
    • 2019-11-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-20
    • 1970-01-01
    相关资源
    最近更新 更多