- PR -

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

投稿者投稿内容
フジタ
常連さん
会議室デビュー日: 2007/10/19
投稿数: 23
お住まい・勤務地: 茨城県
投稿日時: 2007-12-05 08:12
取り急ぎ。
やはり、教えていただいた事を実行させていただきます。
フジタ
常連さん
会議室デビュー日: 2007/10/19
投稿数: 23
お住まい・勤務地: 茨城県
投稿日時: 2007-12-05 09:57
nagiseさん
下記のように実行しました。

System.gc();を実行しないプログラムreal_time_dataをDWR経由で 数回実行すると、

どんどんfreeメモリが減って行きますが、real_time_data2をDWR経由で実行すると減っていく前の元に戻ります。(大体です。)100回位試しましたが。

しかし、1日稼動させると、PF使用量が600→1000位に増えています。

特に、GCで整理できないようなメモリーを作っている部分は無いと思うのですが、
リークしているのでしょうか?もしくは強制でGCを行った方がいいのでしょうか?
よろしくお願い致します。




public String[][] real_time_data2() {
Runtime runtime = Runtime.getRuntime();

String[][] stringArray = new String[10][20];

long max2 = runtime.maxMemory();
long free2 = runtime.freeMemory();
long usd2 = max2 - free2;

System.gc();

long max = runtime.maxMemory();
long free = runtime.freeMemory();
long usd = max - free;

stringArray[0][1] = String.valueOf(max / 1000);
stringArray[0][2] = String.valueOf(free / 1000);
stringArray[0][3] = String.valueOf(usd / 1000);

stringArray[1][1] = String.valueOf(max2 / 1000);
stringArray[1][2] = String.valueOf(free2 / 1000);
stringArray[1][3] = String.valueOf(usd2 / 1000);

return stringArray;

}
nagise
ぬし
会議室デビュー日: 2006/05/19
投稿数: 1141
投稿日時: 2007-12-05 12:37
Runtime#totalMemory()でJava内でのメモリ総量を確認できます。
この値が増えていっているのであれば、なんらかの回収されないメモリがあると見ていいのではないでしょうか。

メモリリークがあるとなればプロファイラと呼ばれるツールを用いて調査することになるでしょう。
フジタ
常連さん
会議室デビュー日: 2007/10/19
投稿数: 23
お住まい・勤務地: 茨城県
投稿日時: 2007-12-05 16:09
返信ありがとうございます。

TOTALメモリーも特に増えては行かないようです。これは一晩とおしてみないと
なんともいえませんが、今のところ。。

PF使用量の件をもう少し調べてみようと思います。
違うPC(搭載メモリーが2GB)で試しましたが、PFはやはり同じように増えてしまいます。
よって同じように増設しても根本的解決にはならないようです。

なお、TOMCATの設定は iniメモリー 256M max 512M thred 512K

にしてあります。
山本 裕介
ぬし
会議室デビュー日: 2003/05/22
投稿数: 2415
お住まい・勤務地: 恵比寿
投稿日時: 2007-12-05 17:19
ヒープ使用量やプロセスサイズが増えるのは極々普通のことです。
負荷をかけて OutOfMemoryError にならなければたぶん大丈夫です。
フジタ
常連さん
会議室デビュー日: 2007/10/19
投稿数: 23
お住まい・勤務地: 茨城県
投稿日時: 2007-12-06 10:46
インギさん 返信ありがとうございます。

>>ヒープ使用量やプロセスサイズが増えるのは極々普通のことです。
負荷をかけて OutOfMemoryError にならなければたぶん大丈夫です。

今回、Netbeansを使うようになって、開発用PCのメモリー増強をしました。
それまで、256MBもあれば普通にPCは使えると思っていました。

昔は64MB(16x4枚)でも十分パソコンは使えていて、
98もXPもそれほど見た目は変わらないと思いますが、進化して
燃費が悪くなるのは、正常な進化ではないような気がします。

このまま、コミットチャージが1.5GB未満程度で推移するようであれば
サーバーPCのメモリーを増強して様子を見ようと思います。

ありがとうございました。
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2007-12-06 10:59
引用:

フジタさんの書き込み (2007-12-05 16:09) より:
PF使用量の件をもう少し調べてみようと思います。
違うPC(搭載メモリーが2GB)で試しましたが、PFはやはり同じように増えてしまいます。
よって同じように増設しても根本的解決にはならないようです。


引用:

フジタさんの書き込み (2007-12-06 10:46) より:
このまま、コミットチャージが1.5GB未満程度で推移するようであれば
サーバーPCのメモリーを増強して様子を見ようと思います。


やはり、メモリーを増設することは、一時的な対処にはなっても根本的な解決ではないはずです。(借金癖のある家族の借金を肩代わりするようなものです。)
もっとも、運用上、動かなくなる時期を遅らせることは、ある程度の解決であるともいえます。
しかし、正しいプログラムかどうか、という観点で見る限りは、やはり、メモリーを増設するのは根本的な解決ではないでしょう。

引用:

フジタさんの書き込み (2007-12-04 14:59) より:
問題の部分のウインドウを閉じると消費が止まったので、DWRの部分が原因だと思いました。


私は DWR を知らないのですが、クライアント側のPCの「ウインドウを閉じる」と、サーバー側のPCのメモリー消費量が減少する(メモリーの空きが回復する)ということでしょうか?
クライアント(ブラウザー)をサーバーと同じPCで動かされているわけではないのですよね?

なんらかの(広義の)セッションオブジェクトにオブジェクトをどんどん詰め込んでいって、不要になっても開放せず、それが「ウインドウを閉じる」ことでセッションが開放されているような感じもします。だとしたら、やっぱりアプリケーションで作りこんだメモリーリークのバグだと思います。
もしも、セッションをシリアライズしてメモリーから退避させるような機能があると、メモリーの消費量は使えるだけ使うので増えるけど、OutOfMemoryError にはならない(動かなくなるということまでは行かない)、ということはあるかもしれません。
フジタ
常連さん
会議室デビュー日: 2007/10/19
投稿数: 23
お住まい・勤務地: 茨城県
投稿日時: 2007-12-07 08:59
返信ありがとうございます。unibonさん

私は業務でCとVBをよく使います。っでJAVAは初心者のようなものです。
HTMLから始まり、Script・Jfreeチャート・サーブレット・tomcatの設定・
apatchとの連携など、どれも少しずつかじる程度しか出来ません。(完全に理解するまで、どれも勉強しだしたらいつまで掛かるか判らない程の奥の深さを感じます)
また、色々な技術があり、世界の広がりを感じています。

確かに今までの経験では、メモリーがリークしていると思いましたが、諸先輩方からの意見で
もしかしたらこんなものなのかも知れない。とも思い始めました。

いままでの経験から255MBで十分だと思っていた家のPCを1GBまでメモリ増強しなければならないと思わせた、JAVA。パソコンの中ではアイドルが侍に変わる程の事が起きているのを実感しました。

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

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

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






引用:
-------------------------------------------------------------------------------

やはり、メモリーを増設することは、一時的な対処にはなっても根本的な解決ではないはずです。(借金癖のある家族の借金を肩代わりするようなものです。)
もっとも、運用上、動かなくなる時期を遅らせることは、ある程度の解決であるともいえます。
しかし、正しいプログラムかどうか、という観点で見る限りは、やはり、メモリーを増設するのは根本的な解決ではないでしょう。

私は DWR を知らないのですが、クライアント側のPCの「ウインドウを閉じる」と、サーバー側のPCのメモリー消費量が減少する(メモリーの空きが回復する)ということでしょうか?
クライアント(ブラウザー)をサーバーと同じPCで動かされているわけではないのですよね?

なんらかの(広義の)セッションオブジェクトにオブジェクトをどんどん詰め込んでいって、不要になっても開放せず、それが「ウインドウを閉じる」ことでセッションが開放されているような感じもします。だとしたら、やっぱりアプリケーションで作りこんだメモリーリークのバグだと思います。
もしも、セッションをシリアライズしてメモリーから退避させるような機能があると、メモリーの消費量は使えるだけ使うので増えるけど、OutOfMemoryError にはならない(動かなくなるということまでは行かない)、ということはあるかもしれません。

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