2013-10-14 2 views
0

J'ai écrit une application Java qui utilise JNI pour appeler une bibliothèque native personnalisée. La bibliothèque fonctionne bien, nous passons pour de petites baies de données. Cependant, des tableaux de données plus volumineux provoquent une erreur fatale (EXCEPTION_STACK_OVERFLOW). Le core dump de l'application montre la fonction offensante _chkstk. Apparemment, _chkstk est appelé par le compilateur lorsque vous avez plus d'une page de variables locales dans votre fonction.Crash d'application Java JNI en raison d'un dépassement de pile

--------------- 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 

Une recherche rapide m'a conduit sur le site d'Oracle qui décrit en détail ce qui se passe 4.1.3 Crash due to Stack Overflow et propose des moyens pour corriger le problème 1) augmenter la valeur de StackShadowPages (vérifie une quantité d'espace minimum reste sur la pile) 2) augmentez la taille de la pile de threads par défaut en utilisant le paramètre -Xssparameter.

Ce qui n'est pas clair, c'est de savoir combien ces valeurs devraient être augmentées. Plutôt qu'une approche shotgun je voudrais déterminer cela mathématiquement. Cela peut-il être déterminé à partir des pointeurs de la pile dans le vidage?

Répondre

0

Vous ne pouvez pas déterminer à partir de la manière dont il s'est écrasé pendant combien de temps le programme a pu fonctionner ou à quelle profondeur il aurait pu être si vous l'avez laissé.

Il n'apparaît pas très profond, il semble donc que vous essayez d'allouer un grand tableau sur la pile au lieu d'utiliser le tas. Comme la taille de la pile est limitée, j'utiliserais le tas natif pour des allocations aussi importantes.

Bien sûr, il s'agit plus d'une question de programmation C que d'une programmation Java.

+0

convenu. c'est un peu plus compliqué que je l'ai décrit cependant, les grands tableaux multidimensionnels sont alloués en C (comme mémoire contiguë et passés à FORTRAN). Peut-être que la façon dont je déclare le paramètre en FORTRAN réel (C_DOUBLE), intention (en), dimension (0: 7 * 3 * 2 * 99) :: bigarray provoque l'allocation sur la pile. Nouveau sur FORTRAN. Besoin d'enquêter. – javacavaj

+0

@javacavaj En attendant vous devrez utiliser '-Xss' pour augmenter le maximum de la pile. Note: ceci affecte tous les threads. : P –

0

IBM spécifique Notez que vous pouvez afficher les tailles de piles existantes avec

java -verbose:sizes 

Lors de l'exécution d'une application Java, vous pouvez modifier la taille initiale de la pile pour les fils du système d'exploitation avec

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

Voir IBM Java -Xmso doc

Questions connexes