2013-10-14 148 views
0

我編寫了一個使用JNI調用自定義本機庫的Java應用程序。該圖書館工作正常,我們通過小數據陣列。但是,較大的數據數組會導致致命錯誤(EXCEPTION_STACK_OVERFLOW)。應用程序的核心轉儲顯示違規函數_chkstk。顯然,當你的函數中有多個局部變量頁時,編譯器會調用_chkstk。由於堆棧溢出導致Java JNI應用程序崩潰

--------------- 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)使用-Xssparameter增加默認線程堆棧大小。

什麼是不明確的是這些值應該增加多少。相反,我想用數學方法來確定這個霰彈槍的方法。這可以通過轉儲中的堆棧指針來確定嗎?

回答

0

你無法從它崩潰的方式確定程序運行的時間長短,或者如果你允許它運行的程度有多深。

它不會顯得很深,所以它會出現你試圖在堆棧上分配一個大數組而不是使用堆。由於堆棧大小有限,我會使用本地堆進行如此大的分配。

當然這比Java編程更像一個C編程問題。

+0

同意。然而,我描述的更復雜一點,大型多維數組在C中分配(作爲連續內存並傳遞給FORTRAN)。也許我在FORTRAN real(C_DOUBLE),intent(in),dimension(0:7 * 3 * 2 * 99):: bigarray中聲明參數的方式會導致堆棧上的分配。 FORTRAN新手。需要調查。 – javacavaj

+0

@javacavaj在此期間,您可能不得不使用'-Xss'來增加堆棧的最大值。注意:這會影響所有線程。 :P –

0

IBM特定 注意,您可以用

java -verbose:sizes 

查看現有的堆棧尺寸當運行Java應用程序,你可以更改操作系統線程初始堆棧大小

java -Xmso512k <...other args to run your app..> 

參見IBM Java -Xmso doc