- PR -

配列を返すためのDWRの使い方が悪いのか、メモリがリークする件。

投稿者投稿内容
nagise
ぬし
会議室デビュー日: 2006/05/19
投稿数: 1141
投稿日時: 2007-12-07 12:30
引用:

フジタさんの書き込み (2007-12-07 08:59) より:
>>なんらかの(広義の)セッションオブジェクトにオブジェクトをどんどん詰め込んでいって、不要になっても開放せず、それが「ウインドウを閉じる」ことでセッションが開放されているような感じもします。だとしたら、やっぱりアプリケーションで作りこんだメモリーリークのバグだと思います。
-----------------------------------------

取説に
「setAttribute(String, Object)
すでにデータ名が存在する場合は、新しく指定されたデータ値が上書きされます。」
とありますが、

クライアントがずっとつなぎっぱなしっでセッションオブジェクトを定期的に同じ
データ名で作るのですが、それは該当するのでしょうか?



セッションオブジェクトの使い方がどうなっているのかわかりませんが、
「不要になっても開放せず」をどういった意味で捉えているのでしょうか。

JavaはC言語とは違い、明示的にFreeする必要はありませんが、
初期化前のメモリや、解放後のメモリにアクセスすることのないように
利用されている=参照がどこかに保持されているオブジェクトは
ずっとメモリ上に持ち続けます。
当然ながら「不要である」というプログラマの主観では解放されません。

セッションなど、アプリケーションの寿命と近いような長い寿命を持つ
オブジェクトにデータを格納する場合、生きた参照がずっと残るので
ガーベッジコレクタの回収対象にならないということはよく起こります。

setAttribute()周辺などはそういう意味でもリークさせやすい場所でもあります。
セッションのタイムアウトまでの時間はどうなっているか、
また、セッションの中身はどうなっているか、そのあたりを調査すると
何か見えてくるのではないでしょうか。
フジタ
常連さん
会議室デビュー日: 2007/10/19
投稿数: 23
お住まい・勤務地: 茨城県
投稿日時: 2007-12-07 17:48
返信ありがとうございます。nagiseさん

タイムアウトは5分です。しかしクライアント側はつなぎっぱなしで定期的にサーバーにアクセスしてきますので、セッションはタイムアウトにはなっていないと思います。

定期的に呼び出される
サーブレット内で下記のようにuserid(二次元配列)をセットしています。

//HttpSessionインタフェースのオブジェクトを取得
HttpSession session = req.getSession();
//useridデータをsessionスコープで保存
session.setAttribute("userid", userid);

userid(二次元配列)はローカル変数で毎回、同じ名前(userid)同じサイズで
NEW定義しています。
セッション的には上書きされると思っていましたが。別に作るのでしょうか?
だとしたら原因はこれです。

今日は申し訳ありませんが、違う業務にて明日、
セッションの中身を調べてます。よろしくお願い致します


引用:

nagiseさんの書き込み (2007-12-07 12:30) より:

セッションオブジェクトの使い方がどうなっているのかわかりませんが、
「不要になっても開放せず」をどういった意味で捉えているのでしょうか。

JavaはC言語とは違い、明示的にFreeする必要はありませんが、
初期化前のメモリや、解放後のメモリにアクセスすることのないように
利用されている=参照がどこかに保持されているオブジェクトは
ずっとメモリ上に持ち続けます。
当然ながら「不要である」というプログラマの主観では解放されません。

セッションなど、アプリケーションの寿命と近いような長い寿命を持つ
オブジェクトにデータを格納する場合、生きた参照がずっと残るので
ガーベッジコレクタの回収対象にならないということはよく起こります。

setAttribute()周辺などはそういう意味でもリークさせやすい場所でもあります。
セッションのタイムアウトまでの時間はどうなっているか、
また、セッションの中身はどうなっているか、そのあたりを調査すると
何か見えてくるのではないでしょうか。

フジタ
常連さん
会議室デビュー日: 2007/10/19
投稿数: 23
お住まい・勤務地: 茨城県
投稿日時: 2007-12-14 08:41
サーバーのメモリーを2GBに増強しました。


サーバーのブラウザで、アパッチ経由からプログラムを動かしても、メモリの増加はほぼしないのに(数日動かしましたが)、クライアントのブラウザで同じアドレスを表示させるとhttpd.exeプロセスのメモリ増加が著しい事から、どうもプログラムではなくアパッチ自体の設定が悪いのか、メモリを開放しないためにこの現象が起きているようです。

アパッチは2.26 tomcatは5.5です

先輩方、色々な助言を頂きましてありがとうございました。

今は借金癖のある家族の借金を肩代わりしています。

アパッチの日本語取説が読み解けないのですが、
http://httpd.apache.org/docs/2.2/mod/core.html#rlimitmem
仮にこの設定で、使用メモリーを制限した場合超えたときは、どのような動きをするのでしょうか?
ご存知であれば、よろしくお願い致します。

「この設定は Apache の子プロセス自体ではなく、 リクエストを受け付けた Apache の子プロセスから fork されたプロセスに 適用されます。」


-------------------------------------------
RLimitMEM ディレクティブ
説明: Apache の子プロセスから起動されたプロセスのメモリ消費量を制限する
構文: RLimitMEM bytes|max [bytes|max]
デフォルト: 未設定。オペレーティングシステムのデフォルトを使用
コンテキスト: サーバ設定ファイル, バーチャルホスト, ディレクトリ, .htaccess
上書き: All
ステータス: Core
モジュール: core

一つか二つのパラメータをとります。 最初のパラメータは全プロセスに対するリソースのソフトリミットを設定し、 2 番目のパラメータは最大のリソースリミットを設定します。 パラメータには数字か、オペレーティングシステムの最大となる max のどちらかを指定することができます。 最大のリソースリミットを上げるためには、サーバを root で実行するか起動されなければいけません。

この設定は Apache の子プロセス自体ではなく、 リクエストを受け付けた Apache の子プロセスから fork されたプロセスに 適用されます。 これには CGI や SSI から実行されたコマンドが含まれますが、Apache の 親プロセスから fork されたログのパイププロセスなどには適用されません。

メモリリソースのリミットはプロセスあたりのバイト数で表わされます。


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