2016-03-02 136 views
1

我尝试使用Java中的JNA集成DLL。 DLL分配大量内存(〜600MB)。 库被编译为32位版本,所以我需要使用32位JVM。在Java中调用的dll中分配内存错误JNA

我有严重错误,JVM

EXCEPTION_UNCAUGHT_CXX_EXCEPTION (0xe06d7363) at pc=0x772bd928, pid=7976, tid=2444 

详细的信息

siginfo: ExceptionCode=0xe06d7363, ExceptionInformation=0x19930520 0x02dce184 0x6a3853d8 

和堆栈

Stack: [0x023d0000,0x02dd0000], sp=0x02dce0d0, free space=10232k 
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code) 
C [KERNELBASE.dll+0xbd928] 
C [MSVCR120D.dll+0x120b86] 
C [MSVCR120D.dll+0x12c2a1] 
C [face_analysis_libD.dll+0x1157dc] operator new[]+0xc 
C [face_analysis_libD.dll+0xea995] Mat<float>::setSize+0xa5 
C [face_analysis_libD.dll+0xe904e] Recognizer::initialize+0x9e 
C [face_analysis_libD.dll+0xb2bf9] Analyser::initializeAnalyser+0x1c9 

应用程序启动时使用参数

-Xmx1300m -Xms1300m -Xss10m -XX:MaxDirectMemorySize=3g -XX:+PrintHeapAtGC 

可能问题是在JVM上有一些内存限制(库很适合C#)。也许有人有类似的问题,并可以帮助我找到解决方案如何在32位JVM中运行此库。

+0

您的'new []'运算符请求的内存数量很可能过大,并且没有人在等待异常。 – technomage

回答

1

32位应用程序通常限制为2GB的虚拟地址空间。假设你在一个64位的Windows上,如果这个二进制文件是用largeaddressaware标志构建的,那么这个扩展可以扩展到4GB。我认为32位java.exe没有,虽然我没有自己测试过。

因此,如果JVM已经在堆吃了1.3G,为线程堆栈和其他非堆数据结构提供了额外的内存,那么dll就没有剩余空间进行分配。如果它需要进行大量的连续分配,这可能会失败并抛出一个C++异常。

你的选择可能是:

  • 减少堆大小
  • 获得该库的64位版本,而不是
  • 看是否标志着二进制为LARGEADDRESSAWARE帮助,也有工具来做到这一点
+0

将最大堆大小减少到900m'-Xmx900m'对我的情况有所帮助。谢谢。 – wonsz