Java 从动态库调用jni时,JVM堆内存不足
我有一个奇怪的情况:我们有.dll库(让我们称之为“sdk_包装器”),它是java类的包装器,正在打开JRE jvm.dll并使用一些其他的.dll(更具体地说,是PKCS11实现,但我认为这并不重要)Java 从动态库调用jni时,JVM堆内存不足,java,c++,dll,jvm,java-native-interface,Java,C++,Dll,Jvm,Java Native Interface,我有一个奇怪的情况:我们有.dll库(让我们称之为“sdk_包装器”),它是java类的包装器,正在打开JRE jvm.dll并使用一些其他的.dll(更具体地说,是PKCS11实现,但我认为这并不重要) 当我在C++程序中直接使用SDKY-WrasPad(别名“RunEydLL”)时,一切都很好。但当我将它打包到另一个.dll(准备配置文件、初始化库等)并导出一个与程序“run_dll”完全相同的函数时,调用它会导致jvm初始化错误:无法为对象堆保留足够的空间。JVM.dll初始化正在使用-X
当我在C++程序中直接使用SDKY-WrasPad(别名“RunEydLL”)时,一切都很好。但当我将它打包到另一个.dll(准备配置文件、初始化库等)并导出一个与程序“run_dll”完全相同的函数时,调用它会导致jvm初始化错误:
无法为对象堆保留足够的空间。JVM.dll初始化正在使用-Xmx512m
进行
你知道发生了什么事吗?我读到JVM需要连续的内存来初始化,但直接从程序调用“sdk_包装器”和从另一个dll调用“sdk_包装器”有什么区别?它们在同一个位置(我的意思是在同一个目录中)。当您将库加载到内存中时,您将以地址空间的内存碎片结束。Win32在这方面尤其糟糕
注意:如果您使用64位进程,这不是问题,因为您将拥有大量的虚拟内存。好的,那么加载调用java的a.dll和加载调用java的b.dll之间的区别是什么?加载的每个dll都使用一些内存,可能加载在次优位置。JVM需要为堆提供连续内存,这对Windows来说是个问题。它倾向于分割其虚拟地址空间。是的,我明白了-但是为什么直接从.exe
加载sdk\u包装器
不会导致错误,当从另一个.dll
加载它时,你必须问微软为什么要这样设计操作系统。然而,我怀疑即使是他们也不知道,因为当他们实现64位时,他们没有做到这一点。如果你使用64位的JVM和DLL,你就不会有这个问题。现在更奇怪了——当我使用jre8时,它可以工作,但对于旧的jre,它失败了。在这种特殊情况下,我不能使用64位.dll,但我可以使用jre8,所以现在一切正常。无论如何,谢谢你的帮助:)