You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JNI嵌入R至Java时遇C栈溢出及JIT初始化失败求助

问题:嵌入R到Java(JNI)时出现C栈溢出及JIT初始化失败错误

此前已解决编译R的libR库并通过JNI在Java中加载的问题,目前能成功加载libR,但运行时出现以下R错误:

##Trying load RSession
##LOADED !! RSession
RSession.c:Java_RSession_test:15
RSession.c:Java_RSession_initEmbeddedR:21
[0] /path/to/TMP/R-4.3.2/bin/R
[1] --vanilla
[2] --quiet
[3] --encoding=UTF-8
[4] --no-init-file
[5] --no-readline
RSession.c:Java_RSession_initEmbeddedR:35
Error: C stack usage  134897775332 is too close to the limit
Error: C stack usage  134897775380 is too close to the limit
Error: C stack usage  134897775268 is too close to the limit
Fatal error: unable to initialize the JIT

怀疑是R层面的递归问题,但无法定位原因,且HOME目录中无.Renviron、.Rprofile等配置文件。以下是可复现问题的最小代码:

Java代码

public class RSession {
    // 声明本地方法
    public static native int initEmbeddedR(int argc, String[] argv);
    public static native void endEmbeddedR(int fatal);
    public static native void test();

    public static void main(String[] args) throws Throwable {

        final String R_HOME = System.getenv("R_HOME");
            if(R_HOME==null || R_HOME.isEmpty()) {
                System.err.println("undefined R_HOME");
                System.exit(-1);
                }

        final String libName= "RSession";
        System.err.println("##Trying load "+libName);
        try {
            System.loadLibrary(libName);
            }
        catch(Throwable err) {
            System.err.println("##Cannot load "+libName);
            err.printStackTrace();
            System.exit(-1);
            }
        System.err.println("##LOADED !! "+libName);

        test();
        String[] argv = {args[0],"--vanilla","--quiet","--encoding=UTF-8","--no-init-file","--no-readline"};
        
        int result = RSession.initEmbeddedR(argv.length, argv);
        System.out.println("initEmbeddedR returned result: " + result);

        RSession.endEmbeddedR(0);
        System.out.println("endEmbeddedR called successfully");
    }
}

C代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <Rinternals.h>
#include <Rembedded.h>
#include <R_ext/Parse.h>

#include <jni.h>
#include "RSession.h"

#define WHERE fprintf(stderr,"%s:%s:%d\n",__FILE__,__FUNCTION__,__LINE__)

JNIEXPORT void JNICALL Java_RSession_test
  (JNIEnv * env, jclass clazz) {
    WHERE;
   }



JNIEXPORT jint JNICALL Java_RSession_initEmbeddedR(JNIEnv *env, jobject obj, jint argc, jobjectArray argv) {
    WHERE;
    int i;
    int len = (*env)->GetArrayLength(env, argv);
    char **args = (char **)malloc(len * sizeof(char *));
    for (i = 0; i < len; i++) {
        jstring string = (jstring)(*env)->GetObjectArrayElement(env, argv, i);
        const char *rawString = (*env)->GetStringUTFChars(env, string, 0);
        args[i] = strdup(rawString);
         fprintf(stderr,"[%d] %s\n",i,args[i]);
        (*env)->ReleaseStringUTFChars(env, string, rawString);
    }

        WHERE;

    int result = Rf_initEmbeddedR(argc, args);
    WHERE;

    // 释放为C字符串分配的内存
    for (i = 0; i < len; i++) {
        free(args[i]);
    }
    free(args);
    WHERE;
    return result;
}

JNIEXPORT void JNICALL Java_RSession_endEmbeddedR(JNIEnv *env, jobject obj, jint fatal) {
    // 调用C函数
    WHERE;
    Rf_endEmbeddedR(fatal);
    WHERE;
}

Makefile

SHELL=/bin/bash
CC=gcc
R_VERSION=4.3.2

test: TMP/RSession.class  TMP/libRSession.so
    echo | R_HOME=${PWD}/TMP/lib/R PATH=$${PATH}:{PWD}/TMP/R-$(R_VERSION)/bin  java -Djava.library.path=${PWD}/TMP:TMP/R-$(R_VERSION)/lib -cp TMP RSession "${PWD}/TMP/R-$(R_VERSION)/bin/R"

TMP/libRSession.so : RSession.c TMP/R-$(R_VERSION)/lib/libR.so TMP/RSession.h
    $(CC)  -ITMP -I$${JAVA_HOME}/include/ -I$${JAVA_HOME}/include/linux \
        -LTMP/R-$(R_VERSION)/lib `TMP/R-$(R_VERSION)/bin/R CMD config --cppflags` -shared -fPIC -o $@  -g $< -lR


TMP/RSession.h : TMP/RSession.class
    touch -c $@

TMP/RSession.class : RSession.java
    mkdir -p TMP
    javac -h TMP -d TMP $<
    touch $@

TMP/R-$(R_VERSION)/lib/libR.so :
    rm -rvf  "TMP/R-$(R_VERSION)" TMP/jeter.tar.gz
    mkdir -p $(dir $@)
    wget -O TMP/jeter.tar.gz "https://pbil.univ-lyon1.fr/CRAN/src/base/R-4/R-$(R_VERSION).tar.gz"
    (cd TMP && tar xfz jeter.tar.gz && rm jeter.tar.gz &&  cd R-$(R_VERSION) &&  ./configure --with-pcre1 --enable-R-shlib --with-x=no --prefix=${PWD}/TMP && make && make install)

内容的提问来源于stack exchange,提问作者Pierre

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 15:45:56