有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Java JNI调用的数组开销

Possible Duplicate:
What makes JNI calls slow?

首先让我说,这些问题更多地是出于好奇而不是出于真正的需要

我很想知道从Java进行JNI调用,比如说,System.arraycopy与分配数组和使用for循环复制元素相比,开销是多少

如果开销很大,那么可能有一个粗略的“幻数”元素,它只需使用for循环,而不是使用系统调用,就可以对其进行补偿。另外,系统调用中到底涉及到什么导致了这种开销? 我猜堆栈必须被推到调用的上下文中,这可能需要一段时间,但我找不到对整个过程的好解释

让我澄清我的问题:

我知道使用arraycopy是在Java中复制数组的最快方法

也就是说,假设我用它来复制一个只有一个元素的数组。因为我要调用底层操作系统来实现这一点,在这个调用中有的开销。我很想知道这种开销是什么,以及在通话过程中会发生什么

如果使用arraycopy误导了你,使你偏离了我问题的目的,我很抱歉。我想知道JNI调用的开销,以及实际调用中涉及的内容


共 (2) 个答案

  1. # 1 楼答案

    Since I'm calling the underlying OS to do so...

    你说得对system calls相当贵。然而,{}中的{}有点用词不当。没有涉及系统调用

    ...there has to be an overhead in this call. I'm interested in knowing what this overhead is and what happens in the process of the call.

    当你看System.arraycopy()的定义时,它被声明为native。这意味着该方法是用C++实现的。如果你是这样倾向的,你可以看看JDK的源代码,找到C++函数。在OpenJDK 7中,它被称为JVM_ArrayCopy(),并生活在hotspot/src/share/vm/prims/jvm.cpp。实现过程异常复杂,但本质上是一个^{}

    如果arraycopy()被用作正常的本机函数,那么调用它会有开销。参数检查等会导致更多开销

    然而,很可能JIT compiler知道System.arraycopy()。这意味着,编译器不知道调用C++函数,而是知道如何生成专门编写的机器代码来执行数组复制。我不知道其他JVM的情况,但HotSpot确实对System.arraycopy()有这样的“内在”支持

    Let's say I'm using it to copy an array of only one element

    如果你的数组很小,你可以用手工制作的循环来击败System.arraycopy()。如果在编译时知道循环的大小,可能会做得更好,因为这样也可以展开循环。然而,除了在最狭隘的情况下,所有这些都不是真正相关的

  2. # 2 楼答案

    I'm interested to know the overhead of a JNI call, and what's involved in the actual call.

    System.arraycopy()方法相当复杂,*,JIT编译器不太可能将其内联(如其他答案之一所示)

    另一方面,JIT编译器很可能使用优化的调用序列,因为这是一种固有的本机方法。换句话说,这很可能不是正常的JNI调用


    *-System.arraycopy不是一个简单的内存拷贝。它必须测试其参数,以避免读取或写入超出数组边界的内容,等等。在从一个对象数组复制到另一个对象数组的情况下,可能需要检查复制的每个对象的实际类型。所有这些加起来的代码远远超出了内联的合理范围