与C++和JNI共享内存分配

3
我正在使用SWIG编写Java的C++程序包装器。当我从Java中调用一个函数来创建一个大的C++对象时,Java并不知道它已经分配了很多内存,因为它没有在Java的堆中分配。问题是垃圾收集器在对象被删除时不会被调用,因为从Java的角度来看有足够的空闲内存。我尝试实现这里描述的方法:http://www.swig.org/Doc1.3/Java.html#java_heap_allocations。这个想法是在Java的堆中为C++分配内存空间。由于我不想在每个new上使用它,所以我重命名了newdelete,并在需要的地方从我的C++代码中显式使用它们。
这种机制似乎有效(我可以看到Java的堆正在增长,并且通过垃圾收集器缩小),但不幸的是我遇到了随机崩溃,似乎发生在memcpy过程中。
如果我手动调用垃圾收集器,我的程序可以正常工作,但这并不是一个非常干净的方法。
感谢任何线索。

不幸的是,由于大多数Java实现调用malloc和free,这种解决方案对于C封装结构将无法工作。你已经检查过这不是你的情况了吗? - Viruzzo
2
你希望Java从其堆中为你提供内存,并在你不再需要该对象之前不进行垃圾回收。Java如何知道后者何时发生? - sharptooth
请查看我帖子中的链接,您会发现delete运算符调用了env->DeleteGlobalRef(pJalloc->ref); env->ReleaseByteArrayElements - Yann Sagon
2
很有可能你的程序里有漏洞。混合使用各种分配器听起来像是制造奇怪的memcpy错误的配方。 - David Heffernan
崩溃是否真正是随机的? 你是否每次都在特定的memcpy上崩溃? 此外,你能否在调试器中捕获崩溃并打印出src、dest值以及崩溃时的回溯(backtrace)? - chetan
显示剩余2条评论
2个回答

2
事实上,我没有注意到swig网站上的以下行:

如果您要使用gcc打开优化(例如-O2),请确保还使用-fno-strict-aliasing进行编译

这似乎解决了问题。


1

你是否可以通过SWIG手动调用C++对象析构函数呢?这对我来说似乎有效。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接