gpt4 book ai didi

java - 如何避免在 Java 和 native C++ 代码之间复制数据

转载 作者:太空宇宙 更新时间:2023-11-03 10:36:37 27 4
gpt4 key购买 nike

我正在编写 C++ 库,不同的 Android 应用程序将使用它来处理某种组织的数据,如二维存储,其中每个维度都没有预定义的大小限制(如 float 组的数组,数组的大小可以相当大)。

当前的解决方案使用 SWIG 将数据从 Java 代码分配的内存复制到 C++ 结构。事实证明,每个浮点值数组(在 Java 中)都变成了浮点 vector (在 C++ 中)。

问题在于,大量数据的重复会增加应用程序可用内存耗尽的风险。我明白,在任何情况下,内存消耗问题都应该通过输入量限制来解决,但是库不知道有多少内存可用并且应该有完整的数据(需要重复访问任何数据元素)来执行正确的处理。

所以现在我正在考虑为 Java 和 C++ 使用一个数据存储的可能性,因此 C++ 代码需要直接访问 Java 代码存储的数据到 Java 端分配的内存(不考虑将 C++ 代码分配的内存作为单一存储).

我想知道如何以安全的方式组织此类内存共享(最好使用 SWIG)。

我觉得这样的实现可能会有一些困难,例如使用 Java 垃圾收集器(C++ 代码可以寻址到已经释放的存储)并通过包装器减慢内存访问(如前所述,库需要重复访问每个数据项)……但也许有人建议我一个可靠的解决方案。如果有充分和令人信服的论据支持,我的想法为什么错误的解释可以被接受。

最佳答案

您可以使用Critical Native 实现访问原始 数据数组。此技术允许直接访问 jvm 内存,而无需在 Java 和 native 代码之间传输数据。

但这有下一个限制:

  • 必须是静态的且不同步;
  • 参数类型必须是原始类型或原始数组;
  • 实现不得调用 JNI 函数,即它不能分配 Java 对象或抛出异常;
  • 不应长时间运行,因为它会在运行时阻塞 GC。

critical native 的声明看起来像一个常规的 JNI 方法,除了:

  • JavaCritical_开头,而不是Java_
  • 它没有额外的 JNIEnv*jclass 参数;
  • Java 数组通过两个参数传递:第一个是数组长度,第二个是指向原始数组数据的指针。也就是说,无需调用GetArrayElements 和 friend ,您可以立即使用直接数组指针。

original answersource article了解详情。

关于java - 如何避免在 Java 和 native C++ 代码之间复制数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42983298/

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