Java JNI 应用程序因堆栈溢出而崩溃

标签 java c java-native-interface

我编写了一个 Java 应用程序,它使用 JNI 来调用自定义 native 库。该库工作正常,我们传入小数据数组。但是,较大的数据数组会导致 fatal error (EXCEPTION_STACK_OVERFLOW)。应用程序的核心转储显示有问题的函数 _chkstk。显然,当函数中有不止一页的局部变量时,编译器会调用 _chkstk。

    ---------------  T H R E A D  ---------------

    Current thread (0x3590b800):  JavaThread "pool-2-thread-8" [_thread_in_native, id=11228, stack(0x0f7d0000,0x0f9d0000)]

    siginfo: ExceptionCode=0xc00000fd, ExceptionInformation=0x00000000 0x0f7d0000 
...


    Stack: [0x0f7d0000,0x0f9d0000],  sp=0x0f9b7118,  free space=1948k
    Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
    C  [b.dll+0xbfc7]  _chkstk+0x27
    C  [b.dll+0xbf00]  more_calcs+0x60
    C  [b.dll+0xbe1c]  b+0x3c
    C  [a.dll+0x14b0]  more_calcs+0xc0
    C  [a.dll+0x109c]  calcs+0x3c
    C  [x.dll+0x1b75]  Java_com_...s+0x8f5
    j  com.s...(Ljava/lang/String;IIIII[D[D[D[[[I[[[[D[[[[[[D)[[[[D+0

快速搜索后我进入了 Oracle 网站,其中详细描述了正在发生的事情 4.1.3 Crash due to Stack Overflow并提出了纠正该问题的方法:1) 增加 StackShadowPages 的值(验证堆栈上剩余的最小空间量)2) 使用 -Xss 参数增加默认线程堆栈大小。

尚不清楚这些值应该增加多少。我想用数学方法来确定这一点,而不是霰弹枪方法。这可以从转储中的堆栈指针确定吗?

最佳答案

您无法根据程序崩溃的方式确定程序可能运行了多长时间,或者如果您让它运行的话,程序可能会运行多深。

它看起来不是很深,因此看起来您正在尝试在堆栈上分配一个大数组而不是使用堆。由于堆栈大小有限,我将使用 native 堆来进行如此大的分配。

当然,这更像是一个 C 编程问题,而不是 Java 编程问题。

关于Java JNI 应用程序因堆栈溢出而崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19352066/

相关文章:

java - 在使用 va_arg 传递 char* 时,在 JNI 中将 char* 转换为 jstring

Java正则表达式防止匹配特定关键字

java - 模块声明中的 requires 和 requires static 有什么区别

android - 使用大图时如何使用JNI位图操作避免OOM?

android - fopen() 不重置文件

c - 在 C 的 doxygen 文档中扩展非函数宏

java - 如何处理JavaCPP避免数据复制?

java - GSON 数组到 json 但映射数组

java - 我们如何在 Android/java 中将新元素推送到 firestore Map 类型数组中?

c - 将结构保存在文件中