gpt4 book ai didi

java - NewDirectByteBuffer 是否在 native 代码中创建拷贝

转载 作者:太空狗 更新时间:2023-10-29 20:57:59 26 4
gpt4 key购买 nike

我正在用 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 实现和操作系统而异。问题是您的直接内存必须在 DirectByteBuffer 的生命周期内保持有效。由于您的字符串在堆栈上,它会很快超出范围。同时,Java 代码可能会也可能不会继续使用 DirectByteBuffer,这取决于它是什么。你也在写Java代码吗?您能否保证在字符串超出范围之前完成对 DirectByteBuffer 的使用?

即使您可以保证这一点,也要意识到 Java 的 GC 是不确定的。人们很容易认为您的 DirectByteBuffer 不再被使用,但与此同时它在未回收的对象中徘徊,最终被 GC 吸走,GC 可能会调用一些意外触及 DirectByteBuffer 的 finalize() 方法,以及——kablooey!实际上,除了在应用程序的生命周期中永远不会消失的“共享内存” block 之外,很难做出这些保证。

NewDirectByteBuffer 也不是那么快(至少在 Windows 中不是),尽管直觉假设性能就是它的全部。我通过实验发现复制 1000 个字节比创建单个 DirectByteBuffer 更快。让您的 Java 将 byte[] 传递到 C++ 并让 C++ 将字节复制到其中通常快(咳咳,假设它们适合)。总的来说,我提出以下建议:

  1. 调用 NewByteArray() 和 SetByteArrayRegion(),返回结果jBytearray 到 Java,没有后顾之忧。
  2. 如果性能是要求,将 byte[] 从 Java 传递到 C++ 并让 C++ 填充它中。您可能需要两次 C++ 调用,一次获取大小,下一次获取数据。
  3. 如果数据很大,使用 NewDirectBtyeBuffer 和确保 C++ 数据“永远”保留,或者直到您该死的确定 DirectByteBuffer 已被处置。

我还读到 C++ 和 Java 都可以对同一文件进行内存映射,这对于大数据非常有效。

关于java - NewDirectByteBuffer 是否在 native 代码中创建拷贝,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28791827/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com