java - 为什么在 JNI 中调用纤程会在 JVM 中引发 StackOverflow?

标签 java c++ boost java-native-interface fiber

我认为这也是一个难题。反正我想试试。

我实现了一个在 Java 中移植原生 boost fibers 的 JNI 迷你项目。

这是JNI接口(interface)

inline void execute(JNIEnv * env,jobject runnable,jmethodID mid){
 cout <<  " 31---"  << endl;
 env->CallVoidMethod(runnable, mid);
  cout <<  " 32---"  << endl;
}

/*
 * Class:     java_ext_concurrent_fiber_NativeFiber
 * Method:    run
 * Signature: (Ljava/lang/Runnable;)J
 */
JNIEXPORT void JNICALL Java_ext_concurrent_fiber_NativeFiber_run
  (JNIEnv * env, jclass clazz, jobject runnable){
cout <<  " 1---"  << endl;
   jclass cls = env->GetObjectClass( runnable);
   cout <<  " 2---"  << endl;
   jmethodID mid = env->GetMethodID( cls, "run", "()V");
cout <<  " 3---"  << endl;

env->CallVoidMethod(runnable, mid);
  boost::fibers::fiber fiber(execute,env,runnable,mid);

  cout <<  " 3---"  << endl;

  }

这是java测试

public class Test {
    public static void main(String[] args) throws InterruptedException {

        NativeFiber fiber=new NativeFiber(new Runnable() {
            @Override
            public void run() {


                System.out.println("hello");
            }
        });
        fiber.start();


    }
}

如果我执行这段代码

throws StackOverflowException

如果我删除 fiber.join() 并添加 fiber.detach();

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x00007f5a37017f1f, pid=16559, tid=0x00007f5a38522700
#
# JRE version: Java(TM) SE Runtime Environment (8.0_131-b11) (build 1.8.0_131-b11)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.131-b11 mixed mode linux-amd64 compressed oops)
# Problematic frame:
# V  [libjvm.so+0x6d7f1f]  jni_CallVoidMethodV+0x3f
#
# Failed to write core dump. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
#
# An error report file with more information is saved as:
# /data/git/concurrent/hs_err_pid16559.log
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.java.com/bugreport/crash.jsp

最佳答案

可能是因为 Fibers 栈对于 Java 来说太小了。

但是,在没有明确支持的情况下在纤程上运行 JVM/JRE 代码确实是不明智的。

If you have uncovered a part of the JVM specification that explicitly allows it, and you know that the parts of the JRE that you depend on all are safe for use on fibers, you can obviously disregard these words of caution

碰巧的是,JVM/JRE 可能包含任意数量的基于线程模型的假设。例如使用线程本地静态实例对于非同步访问是安全的。这将打破假设并因此导致未指定的行为。

如果您需要纤程,请查看 JVM 支持的方法来实现它们(我无法想象没有流行的库可以做到这一点)。

关于java - 为什么在 JNI 中调用纤程会在 JVM 中引发 StackOverflow?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47959749/

相关文章:

c++ - __m128、__m128d、__m256 等是 C++ 中的内置类型吗?

c++ - 从原始指针到 boost::shared_ptr 的转换:使用 share_from_this 的树实现

C++ 无法解析变量 BOOST_FOREACH

java - 创建名为 'requestMappingHandlerAdapter' Spring Boot 的 bean 时出错

const && 的 C++11 绑定(bind)规则

命名空间和包含文件的 C++ 链接错误

c++ - cmake交叉编译boost链接错误

Javafx - 组合框文本字段背景颜色

java - RESTful 服务客户端可以作为 SOAP 服务的服务器吗?

java - 将行插入 MySQL 数据库?