- PR -

Java(JNI経由)からの起動とExeからの起動の違い

1
投稿者投稿内容
toruchi
会議室デビュー日: 2005/03/28
投稿数: 5
投稿日時: 2005-03-28 10:01
お世話になります。

現在、JavaからJNIを経由して、VCで作成されたあるApplicationのCOM I/Fを利用するプログラムを作成しております。
ところが、そのApplicationの処理の中で、「Stack Overflow」のエラーがでてしまいます。

試しに、VCで作成したExeから同じCOM I/Fを呼び出してみたのですが、こちらではエラーは発生せず、正常に処理が終了します。

Javaの起動オプションとして、「-Xss」によるNative Stackのサイズをいろいろと変更させてみたのですが、常に同じ現象が発生します。

JavaからJNIを経由した場合と、VCで作成したExeから起動した場合で、何が異なるのでしょうか?

実行環境は以下の通りです。
・j2re1.4.2_06
・Windows XP SP2, Windows2000 SP4
パテ太
ベテラン
会議室デビュー日: 2004/08/16
投稿数: 64
お住まい・勤務地: 千葉・東京
投稿日時: 2005-03-28 11:43
少し google で調べてみましたが
http://forum.java.sun.com/thread.jspa?threadID=596209
「-Xss ではメインスレッドのスタックサイズは変えられないので
別のスレッドから呼べ。ないしはネイティブコードのスタックサイズを減らせ。」
というのがありましたので試されてはいかがでしょうか?
toruchi
会議室デビュー日: 2005/03/28
投稿数: 5
投稿日時: 2005-03-28 13:19
お返事ありがとうございます。

早速試してみました。
■別スレッドから呼び出す
・Javaの別スレッドを作成し、そのスレッドからJNI処理を呼び出してみましたが、結果は同じでした。

・また、C++側でもスレッドを作成し、COM I/Fを呼び出してみましたが、Stack Overflowが起こります。

■ネイティブコードのスタックサイズ
(これは、C側のLocal変数の使用領域を削減する、という内容ですよね?)
・Applicationの変更はできない為、ネイティブコードのスタックサイズを減らすことはできません。また、Application COM I/Fを呼び出す為のCコードには、多くの領域を確保するLocal変数は存在しません。

Application側の情報ですが、VCのデフォルトスタックサイズ(=1MB)があれば正常に動くとのことでした。
ちいにぃ
大ベテラン
会議室デビュー日: 2002/05/28
投稿数: 244
投稿日時: 2005-03-28 14:30
試したことありませんが、
C++側でスレッドを作成するとき、スレッドのスタックサイズを指定することが
できたような。_beginthreadとかCreateThread APIにはそういう引数が
あったような‥‥。
自分は以前、スタックを減らすために使った覚えがありますが、
逆にスタックを増やすのにも使えると思います。

ですので、C++でスタックサイズ指定してスレッドを作成→該当処理を実行、で
できそうな気がします。

なお、java.exeのデフォルトのスタックサイズは256KBだったかと。
去年、dumpbinかobjdumpで調べたときはそう(40000H)でした。
toruchi
会議室デビュー日: 2005/03/28
投稿数: 5
投稿日時: 2005-03-28 15:11
ちいにぃさん、お世話になります。

C++でスレッドを作成するAPI:AfxBeginThreadを利用してスレッドを作成しました。
このAPIのパラメータにも、スタックサイズを指定できます。
そのパラメータに1MB〜20MBを指定してみたのですが、やはりStack Overflowのエラーが発生してしまいます。
※スタックの情報を調べてみましたが、設定したスタックサイズが確保されているようです。
toruchi
会議室デビュー日: 2005/03/28
投稿数: 5
投稿日時: 2005-03-28 21:23
お世話になっております。

以下のようにしたところ、とりあえず現象は起きなくなりました。

方法としては、COM I/Fで呼び出しているApplication側でもスレッドを起動していました。
AfxBeginThread()による起動で、StackSizeのパラメータ値は"0"、これはスレッドを作成したプロセスのスタックサイズと同じサイズが指定される、という意味です。

しかし、-Xssで1MB等と指定していても、実際にAfxBeginThread()で確保されるスタックサイズは24KBだったりした為、パラメータに[1024*1024(=1MB)]と記述したところ、Stack Overflowを起すことはなくなりました。

...が理由がよくわかりません。
Javaから起動し、JNIを経由してC++でスレッドを起動すると、Exeで起動した場合とはスタックサイズの確保の仕方が異なるのでしょうか?
ちいにぃ
大ベテラン
会議室デビュー日: 2002/05/28
投稿数: 244
投稿日時: 2005-03-29 00:18
もしかすると、PE Headerのstack sizeが使われているのかも知れません。
もしそうなら、試しにVC++でCOM I/Fを呼ぶとき、VC++側のPE headerのデフォルト値
(1024KB?)をjava.exe並みの256Kに変えて、AfxBeginThreadで確保される
スタックサイズを調べると、わかるかも。
toruchi
会議室デビュー日: 2005/03/28
投稿数: 5
投稿日時: 2005-03-29 17:38
PE Headerのstack sizeとは、プロジェクトの設定のスタックアロケーションで設定する値のことでしょうか?
スタックアロケーションの値を設定して試したのですが、Stack Overflowが起こります。

AfxBeginThreadでスタックサイズパラメータに"0"を指定して起動したスレッドの先頭でスタックサイズを測ってみたのですが、Exe, Javaから実行した場合に同じ値(4KB)となっていました。(こんなに少ないはずはないんですが...)
Javaプロセスのスタックサイズはいくらなのでしょう??-Xossで指定する値なのでしょうか?
1

スキルアップ/キャリアアップ(JOB@IT)