Java 使用更少的内存将位图传递给JNI

Java 使用更少的内存将位图传递给JNI,java,android,c++,java-native-interface,Java,Android,C++,Java Native Interface,在Java中,我让用户选择一个图像文件。然后我对它进行解码,转换成PNG,并传递给JNI。 我怀疑我不需要不断地复制和分配这么多内存。我怎样才能减少这个?是否有一种方法可以检测图像类型是JPEG还是PNG,而不解码和重新编码位图,只传递原始JPEG/PNG数据?或者用更少的分配进行转换?现在它正在消耗大量的内存 爪哇: 在C中,我有以下PickeImage代码: jbyte *b = (jbyte*)env->GetByteArrayElements(data, NULL); jsize

在Java中,我让用户选择一个图像文件。然后我对它进行解码,转换成PNG,并传递给JNI。 我怀疑我不需要不断地复制和分配这么多内存。我怎样才能减少这个?是否有一种方法可以检测图像类型是JPEG还是PNG,而不解码和重新编码位图,只传递原始JPEG/PNG数据?或者用更少的分配进行转换?现在它正在消耗大量的内存

爪哇:

在C中,我有以下PickeImage代码:

jbyte *b = (jbyte*)env->GetByteArrayElements(data, NULL);
jsize dataSize = env->GetArrayLength(data);
byte* imageData = (byte*)malloc(dataSize);
memcpy(imageData, b, dataSize);
env->ReleaseByteArrayElements(data, b, 0);

imageSelectCallback(imageData, dataSize);

使用
java.nio.ByteBuffer
并调用
allocateDirect
函数来分配java和C都可以访问的内存。然后在C中,通过执行以下操作获取指向缓冲区的指针:
env->GetDirectBufferAddress
并通过执行
env->GetDirectBufferCapacity
获取缓冲区的大小

这样,同一枚硬币的两面只共享一个缓冲区。Java和C都将在同一个映像上运行


因此,再次将文件读入一个
java.nio.ByteBuffer
并将其传递给C。如果C需要映像的副本,那么您将别无选择,只能分配2个缓冲区(就像您现在所做的那样)。。我怀疑您不需要副本,而且您可以修改Java提供给您的缓冲区。

看一看-它可能会给您一些提示如果C代码free()将其删除怎么办?Java是如何反应的?如果在C中分配它,则可以在C中释放它。否则,在JNI/Java代码中将对它的所有引用设置为NULL。
jbyte *b = (jbyte*)env->GetByteArrayElements(data, NULL);
jsize dataSize = env->GetArrayLength(data);
byte* imageData = (byte*)malloc(dataSize);
memcpy(imageData, b, dataSize);
env->ReleaseByteArrayElements(data, b, 0);

imageSelectCallback(imageData, dataSize);