我正在 C++ 中创建两个数组,这两个数组将在 java 端读取:
env->NewDirectByteBuffer
env->NewByteArray
这些函数会复制我发送的缓冲区吗?
我是否需要在 C++ 端的堆上创建缓冲区,或者是否可以在堆栈上创建它,因为 jvm 会复制它?
例如这段代码运行正常吗:
std::string stam = "12345";
const char *buff = stam.c_str();
jobject directBuff = env->NewDirectByteBuffer((void*)buff, (jlong) stam.length() );
另一个例子:
std::string md5 "12345";
jbyteArray md5ByteArray = env->NewByteArray((jsize) (md5.length()));
env->SetByteArrayRegion(md5ByteArray, 0, (jsize) (md5.length()), (jbyte*)
md5.c_str());
字符串是在堆栈上创建的。这段代码是否始终有效,或者我是否需要在堆上创建这些字符串并负责在 java 使用完它后将其删除
您对 DirectByteBuffer 的使用几乎肯定会以惊人的、核心转储和不可预测的方式失败。它的行为可能因 JVM 实现和操作系统而异。问题是你的直接记忆must在 DirectByteBuffer 的生命周期内保持有效。由于您的字符串位于堆栈上,因此它很快就会超出范围。同时,Java 代码可能会也可能不会继续使用 DirectByteBuffer,具体取决于它是什么。你也在写Java代码吗?您能否保证在字符串超出范围之前完成对 DirectByteBuffer 的使用?
即使您可以保证这一点,也要意识到 Java 的 GC 是不确定的。人们很容易认为您的 DirectByteBuffer 不再被使用,但同时它在未回收的对象中徘徊,这些对象最终被 GC 清除,GC 可能会调用一些意外触及 DirectByteBuffer 的 Finalize() 方法,还有——卡布卢伊!在实践中,除了“共享内存”块之外,很难做出这些保证never在您的应用程序的整个生命周期中消失。
NewDirectByteBuffer 也不是那么快(至少在 Windows 中不是),尽管直觉上认为性能就是一切。我通过实验发现复制 1000 个字节比创建单个 DirectByteBuffer 更快。通常是much让 Java 将 byte[] 传递给 C++ 并让 C++ 将字节复制到其中(咳咳,假设它们适合)会更快。总的来说,我提出以下建议:
- 调用 NewByteArray() 和 SetByteArrayRegion(),返回结果
jBytearray 到 Java 没有后顾之忧。
- 如果性能是一个
要求,将 byte[] 从 Java 传递到 C++,并让 C++ 填充它
您可能需要两个 C++ 调用,一个用于获取大小,另一个用于获取大小
获取数据。
- 如果数据量很大,使用NewDirectByteBuffer和
确保 C++ 数据“永远”保留,或者直到您
非常确定 DirectByteBuffer 已被释放。
我还了解到 C++ 和 Java 都可以内存映射同一文件,并且这对于大数据非常有效。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)