- PR -

OutOfMemoryErrorとスレッドについて

1
投稿者投稿内容
未記入
会議室デビュー日: 2006/02/12
投稿数: 3
投稿日時: 2006-02-12 14:43
初めまして。
現在どうしても解決できないことがあって悩んでいるので、
もしなにかよい解決手段をお持ちの方がいらっしゃいましたら、
ぜひ御教授いただきたいと思いまして投稿させて頂きます。


現在、以下の仕様のサーブレットアプリケーションをつくっています。

1: ユーザは、投稿フォームより任意のスクリプトプログラムを投稿し、実行することができる
2: このスクリプト言語とは、当方が作成した独自言語で、インタプリタはJava製です。JavaAPIの一部を直接実行することができます(BeanShellのような感じです)

実行環境は以下の通りです。
Fedora Core 4
JDK5.0 update 6

さて、悪戯好きのあるユーザAが、たとえば以下のようなプログラムを書いて投稿した場合、OutOfMemoryErrorが発生してしまうわけですが、
これを、ユーザAが発行したリクエストを処理しているスレッド内に封じ込めることは可能でしょうか?

コード:

buf = new StringBuffer()

while(true) buf.append('!')



現在のままでは、OutOfMemoryErrorが発生するのが「ユーザAのリクエストを処理するスレッドとは限らない」ため、他のユーザに影響が出てしまいます。

そもそもOutOfMemoryErrorが発生しないようにできれば、それが一番いいのでしょうが、現時点ではそのような実装にできそうにないので、OutOfMemoryErrorをうまくハンドリングする方向で行こうと思っています。

どうかよろしくお願いします。

[ メッセージ編集済み 編集者: 未記入 編集日時 2006-02-12 14:51 ]
かつのり
ぬし
会議室デビュー日: 2004/03/18
投稿数: 2015
お住まい・勤務地: 札幌
投稿日時: 2006-02-12 20:34
実行部分をtry/catchでOutOfMemoryErrorをハンドルすることが可能ですよ。
未記入
会議室デビュー日: 2006/02/12
投稿数: 3
投稿日時: 2006-02-12 20:45
ご回答ありがとうございます。

確かに、ご指摘の方法でOutOfMemoryErrorを抑制することは可能ですが、
catchしたスレッドが、「ユーザAのリクエストを処理するスレッド」であるとは限らないため、
たとえば「あなたがポストしたプログラムはOutOfMemoryErrorで終了しました」と
ユーザに表示したとしても、それを見るのはユーザAではなく、偶然同時にプログラムをポストしたユーザBかもしれません。

スレッド毎にメモリを管理しているわけでないjavaでは、
このようなことを避けるのは無理なのでしょうか…
かつのり
ぬし
会議室デビュー日: 2004/03/18
投稿数: 2015
お住まい・勤務地: 札幌
投稿日時: 2006-02-12 22:58
例えば、
コード:

OutOfMemoryError e = null;
try{
new Runnable(){
public void run(){
//処理
}
}.run();
}catch(OutOfMemoryError e1){
e = e1;
}

if(e != null){
//エラーの有無のレポート処理
}


みたいな事をサーブレット内で行えば、
実行中のスレッドに影響をあたえませんよ。
どうしても気になるのであれば、

1.別スレッドを作成
2.JDK5.0から対応しているjava.lang.Thread.UncaughtExceptionHandlerを設定
3.スレッド実行
4.スレッド終了まで待機
5.java.lang.Thread.UncaughtExceptionHandler経由で例外の発生の有無を確認

という方法もあります。


[ メッセージ編集済み 編集者: かつのり 編集日時 2006-02-12 23:01 ]
あしゅ
ぬし
会議室デビュー日: 2005/08/05
投稿数: 613
投稿日時: 2006-02-13 00:37
他のスレッドに全く影響が出ないかっていうと、微妙なとこじゃないですか?
OutOfMemoryErrorが飛ぶ瞬間に他のスレッドがメモリを確保したとすると、
そちらのスレッドでもOutOfMemoryErrorとなる可能性はあるわけで。

まぁ、この手のイタズラならば、多量のメモリを一度に確保しようとして
起こるわけで、小さいメモリブロックなら確保できる可能性が高いですけど。
かつのり
ぬし
会議室デビュー日: 2004/03/18
投稿数: 2015
お住まい・勤務地: 札幌
投稿日時: 2006-02-13 01:02
>あしゅさん
確かにそういう意味では、全く影響がないとは言い切れませんね。
どこで問題が発生したかという情報を知ることができる可能性が高まる程度です。
ちょっと誤解を招く発言だったかも・・・

>未記入さん
一番安全なパターンとしては、別VMを起動して、
そのVMに実行させるパターンでしょう。
実行結果を入力ストリーム(エラーストリーム)や
VM間通信で取得するのがいいと思います。
未記入
会議室デビュー日: 2006/02/12
投稿数: 3
投稿日時: 2006-02-13 17:03
みなさん、ご回答を頂きどうもありがとうございます。
どうやら、手段はなさそうですね。

確かに、別プロセスにして実行すれば別ユーザに影響が出ることはなくなりますが、
そのかわりリクエスト毎にプロセスを起動することになってしまい、オーバーヘッドが大きくなってしまうというデメリットが生じてしまいます。
それでは、そのプロセスをプーリングすればいい、という議論になると
どんどん間違った方向に行ってしまうので、今回はこの辺が限度ですね…


ここは最初に立ち戻って、別のアプローチを考えてみることにします。

どうもありがとうございました。
1

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