在64位Win 7的32位JVM中读取C++中的JNI-ByteBuffer时发生访问冲突

2020年4月6日 15点热度 0条评论

我正在尝试用Java构建SIP客户端。作为SIP框架,我使用doubango。为了显示视频,我正在通过JOGL使用OpenGL,但这并不重要,因为在测试过程中,我实际上是从JOGL中分离了ByteStream。

首先,该视频在带有32位VM的Win 7上运行良好。这些库无法为64位编译,因此我必须在64位系统上使用32位VM,我认为应该可以正常工作。不幸的是,我只能观看视频几秒钟,然后崩溃,并显示“javaw.exe中0x774315de的未处理异常:0xC0000005:访问冲突读取位置0xdddddde9”。

在Visual Studio中进行调试显示,该异常发生在以下行中:

memcpy((void*)m_ConsumeBuffer.pConsumeBufferPtr, pBuffer, nRetsize);

(
http://code.google.com/p/doubango/source/browse/branches/2.0/doubango/bindings/_common/ProxyConsumer.cxx#710)

因此,显然,在对该方法进行数百次调用后,就会发生该错误(因为视频会正确显示一段时间)。

为了缩小可能的原因,我仅在测试中实现了传入视频。

doubango从我在Java中的实现获取指向ByteBuffer的指针,如下所示:

videoFrame = ByteBuffer.allocateDirect(frameSize);
consumer.setConsumeBuffer(videoFrame, frameSize);

consumer是doubango自己的
ProxyVideoConsumer,我在构建时从中得到。

我对C++调试不太熟悉,因为我对Java和Delphi有更丰富的经验,但是我相信我有信心说似乎发生了某种堆损坏。

我目前的假设是,当在64位计算机上运行32位JVM时,JVM的
ByteBuffer.allocateDirect(..)-函数无法正确运行,但是我当然会误解。

有趣的是,在大约50次测试中有两次,视频稳定了5-10分钟,没有任何性能下降或明显的内存泄漏。但是这种“伪随机性”与我在Delphi中处理内存分配问题的经验是一致的。

如果有人可以帮助我,我将感到非常高兴,因为我已经不知道如何使它稳定运行了。

问候,

CSp

解决方案如下:

我想我自己解决了这个问题。显然,当发生错误时,此时pBuffer已被释放/无效。到目前为止,我一直跟踪错误,即使JVM中仍然保留着引用,JVM也会以随机的间隔释放包含缓冲区的sipSession

将垃圾收集器置于 Debug模式也没有太多启示,因为此时它没有记录任何处置对象的意图。实际上,错误仅在几秒钟后发生,因此GC当时并未尝试释放任何内容。

我找到了一个实例,在该实例中我过早地释放了sipSession,这降低了错误发生的频率,但是所有其他处置都具有导致GC的堆栈跟踪。