是什么让JNI电话变慢?

我知道在Java中进行JNI调用时'跨越边界'的速度很慢。

但是我想知道它是什么让它变慢? 底层jvm实现在进行JNI调用时会做些什么,使其非常慢?


首先,值得注意的是,通过“缓慢”,我们正在谈论可能需要几十纳秒的事情。 对于微不足道的本地方法,2010年我在Windows桌面上测量的平均通话时间为40 ns,在我的Mac桌面上通话时间为11 ns。 除非你打了很多电话,否则你不会注意到。

也就是说,调用本地方法可能比创建普通的Java方法调用慢。 原因包括:

  • 本机方法不会被JVM内联。 它们也不会针对这台特定的机器进行即时编译 - 它们已经被编译。
  • 可以复制Java数组以便用本机代码访问,并稍后复制回来。 成本可以是数组大小的线性。 我测量了10万个阵列的JNI拷贝,平均在我的Windows桌面上约为75微秒,在Mac上为82微秒。 幸运的是,可以通过GetPrimitiveArrayCritical或NewDirectByteBuffer获得直接访问。
  • 如果方法传递了一个对象,或者需要进行回调,那么本地方法可能会自己调用JVM。 从本地代码访问Java字段,方法和类型需要类似于反射的东西。 签名在字符串中指定并从JVM查询。 这既缓慢又容易出错。
  • Java字符串是对象,具有长度并被编码。 访问或创建字符串可能需要O(n)副本。
  • 一些额外的讨论,可能过时了,可以在Steve Wilson和Jeff Kesselman的“Java:Platform Performance:Strategies and Tactics”2000年的“9.2:检查JNI成本”一节中找到。 这是关于这个页面的三分之一,在下面的@Philip的评论中提供。

    2009年IBM developerWorks论文“使用Java本地接口的最佳实践”提供了一些避免JNI性能缺陷的建议。


    基本上,JVM解释性地为每个JNI调用构造C参数,并且代码没有被优化。

    本文中列出了更多的细节

    如果您对基准JNI与原生代码感兴趣,则此项目具有运行基准测试的代码。


    值得一提的是,并不是所有用native标记的Java方法都是“慢”的。 其中有些是内在的,使他们非常快。 要检查哪些是内在的,哪些不是,可以在do_intrinsic处查找do_intrinsic。

    链接地址: http://www.djcxy.com/p/86179.html

    上一篇: What makes JNI calls slow?

    下一篇: Milliseconds compare in php