是否有可能使用sun.misc.Unsafe调用C函数没有JNI? [英] Is it possible to use sun.misc.Unsafe to call C functions without JNI?

查看:306
本文介绍了是否有可能使用sun.misc.Unsafe调用C函数没有JNI?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

A片的C / C ++ code的可以提供JNI方法与函数指针数组。但有一个方法来调用堆栈数组的指针指向,从Java code里面直接的功能(不使用JNI或类似)? JNI莫名其妙地做这样的事情,所以必须有一种方式。如何JNI办呢?它是通过sun.misc.Unsafe?即使不是这样,我们可以使用一些不安全的解决方法,让我们的手在JVM code,做的?

A piece of C/C++ code could provide a JNI method with an array of function pointers. But is there a way to call to the stack the functions that array's pointers are pointing to, directly from inside Java code (without using JNI or similar)? JNI somehow does something like that, so there must be a way. How does JNI do it? Is it via sun.misc.Unsafe? Even if it is not, could we use some Unsafe workaround to get our hands on the JVM code that does that?

我不打算使用商业化当然。我连一个专业的,我只是真的很喜欢编码和我最近一直学习CUDA,所以我想也许我可以用一切混合在一起的实验,但JNI调用的开销会破坏其GPU的目的加速$ C $角

I don't plan to use that commercially of course. I'm not even a professional, I just really enjoy coding and I've been studying CUDA lately so I thought maybe I could experiment with mixing everything together, but the overhead of JNI calls would defeat the purpose of having GPU accelerated code.

推荐答案

JNI已经优化了很多,你应该先试一试。但它的确具有一定的开销,<一个href=\"http://stackoverflow.com/questions/24746776/what-does-a-jvm-have-to-do-when-calling-a-native-method/24747484#24747484\">see详细信息。

Is JNI that slow?

JNI has already been optimized a lot, you should give it a try first. But it indeed has certain overhead, see details.

如果本机函数是简单和通常被称为该开销可能显著。 JDK有一个叫做私有API的关键同乡,以减少调用函数的开销,不需要太多的JNI功能。

This overhead can be significant if a native function is simple and is called frequently. JDK has a private API called Critical Natives to reduce overhead of calling functions that do not require much of JNI functionality.

一个本地方法必须满足以下条件成为一个关键的原生:

A native method must satisfy the following conditions to become a critical native:


  • 必须静态不同步

  • 参数类型必须为原始基本数组

  • 执行不能调用JNI功能,即它不能分配Java对象或抛出异常;

  • 不宜长时间运行,因为它的将阻止GC 在运行。

  • must be static and not synchronized;
  • argument types must be primitive or primitive arrays;
  • implementation must not call JNI functions, i.e. it cannot allocate Java objects or throw exceptions;
  • should not run for a long time, since it will block GC while running.

关键原生的声明看起来像一个普通的JNI方法,除了

The declaration of a critical native looks like a regular JNI method, except that


    ;
  • JavaCritical _ 而不是的Java _ 启动
  • 它没有多余的的JNIEnv * JCLASS 参数;

  • Java数组传递两个参数:第一个是一个数组的长度,第二个是指向原始数组数据。也就是说,不需要调用 GetArrayElements 和朋友,你可以立即使用直接数组指针。

  • it starts with JavaCritical_ instead of Java_;
  • it does not have extra JNIEnv* and jclass arguments;
  • Java arrays are passed in two arguments: the first is an array length, and the second is a pointer to raw array data. That is, no need to call GetArrayElements and friends, you can instantly use a direct array pointer.

例如。 JNI的方法

JNIEXPORT jint JNICALL
Java_com_package_MyClass_nativeMethod(JNIEnv* env, jclass klass, jbyteArray array) {
    jboolean isCopy;
    jint length = (*env)->GetArrayLength(env, array);
    jbyte* buf = (*env)->GetByteArrayElements(env, array, &isCopy);
    jint result = process(buf, length);
    (*env)->ReleaseByteArrayElements(env, array, buf, JNI_ABORT);
    return result;    
}

将变成

JNIEXPORT jint JNICALL
JavaCritical_com_package_MyClass_nativeMethod(jint length, jbyte* buf) {
    return process(buf, length);
}

关键当地人只在热点​​JVM的JDK 7启动。此外支持,关键的版本只从编译code调用。因此,您需要关键和标准执行正确,使这项工作。

Critical natives are supported only in HotSpot JVM starting from JDK 7. Moreover, "critical" version is called only from compiled code. Therefore you need both critical and standard implementation to make this work correctly.

此功能是专为在JDK内部使用。没有公共规格什么的。也许你可以找到的唯一的文档在评论 JDK-7013347

This feature was designed for internal use in JDK. There is no public specification or something. Probably the only documentation you may find is in the comments to JDK-7013347.

这个基准显示关键当地人可以比常规方法JNI快几倍时本机的工作量是非常小的。越长的方法,所述较小的是相对的开销。

This benchmark shows critical natives can be several times faster than regular JNI methods when the native workload is very small. The longer is method, the smaller is relative overhead.

P.S。有一个在JDK正在进行的工作,落实本地MethodHandles,将作为一个更快的替代JNI。
然而,它是不太可能之前JDK出现10

P.S. There is an ongoing work in JDK to implement Native MethodHandles that will serve as a faster alternative to JNI. However it is unlikely to appear prior to JDK 10.


  1. http://cr.openjdk.java.net/~jrose/panama/native-call-primitive.html

  2. http://mail.openjdk.java.net/pipermail/panama-dev/2015-December/000225.html

这篇关于是否有可能使用sun.misc.Unsafe调用C函数没有JNI?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆