什么';这是使用GetPrimitiveArrayCritical和Get<;基本类型>;ArrayRegion? 使用JNI桥接C++和java时,我们总是希望避免不必要的复制。我发现GetPrimitiveArrayCritical可能会给我们提供不复制数组的高机会。但我不完全理解它的限制:
调用GetPrimitiveArrayCritical后,本机代码在调用ReleasePrimitiveArrayCritical之前不应运行较长时间。我们必须将这对函数中的代码视为在“关键区域”中运行。在关键区域内,本机代码不得调用其他JNI函数,或任何可能导致当前线程阻塞并等待另一个Java线程的系统调用。(例如,当前线程不能对另一个Java线程正在写入的流调用read。) 这些限制使得本机代码更有可能获得阵列的未复制版本,即使VM不支持固定 我的问题是:什么';这是使用GetPrimitiveArrayCritical和Get<;基本类型>;ArrayRegion? 使用JNI桥接C++和java时,我们总是希望避免不必要的复制。我发现GetPrimitiveArrayCritical可能会给我们提供不复制数组的高机会。但我不完全理解它的限制:,java,c++,arrays,multithreading,java-native-interface,Java,C++,Arrays,Multithreading,Java Native Interface,调用GetPrimitiveArrayCritical后,本机代码在调用ReleasePrimitiveArrayCritical之前不应运行较长时间。我们必须将这对函数中的代码视为在“关键区域”中运行。在关键区域内,本机代码不得调用其他JNI函数,或任何可能导致当前线程阻塞并等待另一个Java线程的系统调用。(例如,当前线程不能对另一个Java线程正在写入的流调用read。) 这些限制使得本机代码更有可能获得阵列的未复制版本,即使VM不支持固定 我的问题是: 延长时间的确切含义是什么 那么,
这里要理解的关键是,您正在获取这段内存的关键部分(例如锁)
GetByteArrayElements方法不能保证程序使用引用或复制。JNI返回isCopy标志,表示它复制了对象或固定了对象(固定表示引用)。如果您不想永远复制它,就不必使用GetArrayElements方法,因为它总是返回copy(JVM决定是否复制,并且可能优先选择复制,因为复制减轻了垃圾收集器的负担)。我试了一下,发现当发送一个大数组时,我的内存增加了。您还可以在下面的链接中看到: (查看treeview中的副本和pin主题) 如文档所述,GetPrimitiveArrayCritical返回Java数组的直接堆地址,在调用相应的ReleasePrimitiveArrayCritical之前禁用垃圾收集。所以,如果不想复制,就必须使用GetPrimitiveArrayCritical(当你有一个大数组时,你需要它) 要了解GetArrayRegion,您可以阅读以下链接:
我假设,如果您想要获取整个数组,请使用GetPrimitiveArrayCritical;如果您想要获取一个数组,请使用GetArrayRegion。
GetPrimitiveArrayCritical
将阻止所有现有的垃圾收集器。(实验中的Shenandoah收集器通常不会阻塞。)阻塞垃圾收集器将阻塞所有对象分配(一旦垃圾堆积起来)
因此,使用GetPrimitiveArrayCritical
的规则如下:
GetPrimitiveArrayCritical
的性能优势将被完全否定。然而,拖延是不可能的