2017-12-24 31 views
1

나는 이것이 여기에서도 어려운 질문이라고 생각한다. 어쨌든 나는 시험해보고 싶다.JNI 내부에서 파이버를 호출해야하는 이유 JVM에서 StackOverflow를 던집니까?

Java 내부에 기본 부스트 파이버를 포팅하는 미니 프로젝트 JNI를 실현했습니다.

이 자바 테스트

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(); 


    } 
} 

에게이다

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; 

    } 

JNI 인터페이스이다 내가 fiber.join을 (제거하면이 코드

throws StackOverflowException 

실행) 내가 추가하면 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 
+0

예 실제로 주소를 사용하지 않기 때문에 문제가되지 않습니다. 어쨌든 거기에 다음과 같은 문제가 두 번째 시간에 섬유를 검색하는 방법. 어쩌면 이드 ...하지만 어떻게? –

+0

첫 번째 하나, java havent 포인터/인라인 함수 –

답변

0

아마도 Fibers 스택이 Java에 비해 너무 작기 때문일 수 있습니다.

그러나 명시 적으로 지원하지 않고 파이버에서 JVM/JRE 코드를 실행하는 것은 좋지 않습니다. 당신이 명시 적으로, 당신이 모든에 의존하는 JRE의 일부가 섬유에 사용하기 위해 안전하다는 것을 알 수있는 JVM 사양의 일부를 발견 한 경우

, 당신은 분명이 말을 무시할 수 주의 :

그런데 JVM/JRE에는 스레딩 모델을 기반으로하는 여러 가지 가정이 포함될 수 있습니다. 동기화되지 않은 액세스에 안전한 스레드 로컬 정적 인스턴스의 사용. 이것은 가정을 깨고 따라서 불특정 행동으로 이어질 것입니다.

Fibers가 필요한 경우이를 달성하기위한 JVM- 축복 된 방법을 살펴보십시오 (이 작업을 수행 할 수있는 인기있는 라이브러리가 없다고는 상상할 수 없습니다).

+0

나는 16 메가 바이트까지 섬유 스택을 encre 시도했습니다. 같은 오류. 자바에서 C++로 의사 소통 할 방법이 없다. 기본 데이터 형식은 전달하지만 콜백이있는 Java 객체는 전달하지 않습니다 (파이버 내부에서 Java를 호출하는 경우). JNI와 함께 Java 파이버를 사용하면 C++에서 스레드 잠금이 있기 때문에 제대로 작동하지 않습니다. C++ 파이버를 사용하면 작동하지 않습니다 .Fibers는 상호 운용성에 큰 문제를 야기하고 있습니다. –