为什么在JNI中调用光纤会在JVM中抛出StackOverflow?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为什么在JNI中调用光纤会在JVM中抛出StackOverflow?相关的知识,希望对你有一定的参考价值。
我认为这也是一个棘手的问题。无论如何,我想尝试。
我意识到一个迷你项目JNI在Java中移植原生boost光纤。
这是JNI接口
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
答案
可能是因为光纤堆栈对于Java来说太小了。
但是,在没有明确支持的情况下,在光纤上运行JVM / JRE代码是非常不明智的。
如果您发现了明确允许它的JVM规范的一部分,并且您知道您所依赖的JRE部分都可以安全地用于光纤,那么您显然可以忽略这些谨慎的话。
实际上,JVM / JRE可能包含基于线程模型的任意数量的假设。例如使用线程本地静态实例对于非同步访问是安全的。这将打破假设,从而导致未指明的行为。
如果你需要Fibers,请看JVM祝福的方式来实现它们(我无法想象没有一个流行的库来做到这一点)。
以上是关于为什么在JNI中调用光纤会在JVM中抛出StackOverflow?的主要内容,如果未能解决你的问题,请参考以下文章
为啥 requests-mock 装饰器模式会在 pytest 中抛出“fixture 'm' not found”错误?