- PR -

パーマネント領域のメモリーリーク

投稿者投稿内容
DOON
会議室デビュー日: 2008/10/27
投稿数: 11
投稿日時: 2008-12-04 20:16
JDK1.5 Tomcat4.0 struts1.0
で稼働しているシステムで、画面が表示されなくなりました。

OutOfMemoryError: PermGen space
とログを、はいていました。
パーマネント領域が、拡張できずに、無反応になったみたいです。
gcviewerのログで確認しました。
3日で1Mぐらい増えている感じです。

いろいろ調べましたが手詰まりです。
パーマネント領域は
クラス定義や、メソッド、フィールドなどの
メタデータが格納されるということですが、
この領域でメモリーリークって起きるのでしょうか?
そこがよくわかりません。
教えていただけないでしょうか?

もしくは、パーマネント領域の中身を見れるツールがあれば
教えてほしいです。
かつのり
ぬし
会議室デビュー日: 2004/03/18
投稿数: 2015
お住まい・勤務地: 札幌
投稿日時: 2008-12-05 00:17
クラスローダを使い捨てたときに、
システムクラスローダでロードされているオブジェクトから、
使い捨てているはずのクラスローダでロードしているクラス群が、
参照される場合に多いと思います。

Tomcatのコンテキストをリロードしたりしていませんか?
その際、CommonsLoggingのLogFactoryのリリース処理等が抜けてませんか?
DOON
会議室デビュー日: 2008/10/27
投稿数: 11
投稿日時: 2008-12-05 10:59
返事本当にありがとうございます。

reloadable=trueで納品しています。
これはfalseの方がいいのでしょうか?
コンテキストのリロードって、頻繁に起きるのでしょうか?

おっしゃってる感じで、
Tomcat立ち上げ時に
this.logger = Logger.getLogger(AAA.class.getName());
このloggerをServletContextに設定しています。
その処理は、原則一度しか通らないです。
なにか、ログを落としたい時にgetServletContext , getAttribute
で取り出して、ログを書いています。
このloggerの解放処理は、書いていません。

ServletContextには、他にもいくつか設定していますが、
すべて一度きりしか、設定していないようにしています。

クラスローダ、システムクラスローダは初めて聞いたので、
少し勉強してみます。

もし、わかる方がいれば引き続き、よろしく
お願いします。


かつのり
ぬし
会議室デビュー日: 2004/03/18
投稿数: 2015
お住まい・勤務地: 札幌
投稿日時: 2008-12-05 11:56
リロードはクラスを差し替えたときに発生しますが、
納品済みということは、関係なさそうですね。

何か他にライブラリを使ったりしていませんか?
バイトコードのエンジニアリングライブラリ等・・・
DOON
会議室デビュー日: 2008/10/27
投稿数: 11
投稿日時: 2008-12-05 13:42
返事ありがとうございます。
今も、テストしているのですが、不明です。

リロードの意味理解しました。
ありがとうございます。

ライブラリーですか?
オラクルにつないでいます。
Actionのそのつど、コネクションを作成しています。
その作成の時に
Class.forName(this.getAAA().getItem("data-source", "", "db-driver"));
のようにリフレクションでドライバマネージャーを呼んでいます。

リフレクションがパーマネント領域に影響をあたえると
ネットでは出ていましたが、よくわかっていません。

あと、JSPでJSTLは使用しています。

稼働中ですが、ログを落とすために printGCDeatilsオプションで
動かしています。

あと、
JSPの下部に
<meta http-equiv="refresh" content="6" content="no-cache">
を張り付けていて、6秒周期でTomcatに接続して
メッセージを表示しています。
客側で、ボタンを押すのが嫌だということで、
何か異常があればメッセージを表示するために定期的な周期で
見に行っています。
なので、画面を出しっぱなしだとセッションが切れることは
ありません。
現に24時間、画面は出しっぱなしみたいです。


基本的には、同じクラスが何度も呼ばれてしまっている感じなのでしょうか?

もし、わかればご返事よろしくお願いします。
かつのり
ぬし
会議室デビュー日: 2004/03/18
投稿数: 2015
お住まい・勤務地: 札幌
投稿日時: 2008-12-05 20:30
引用:

ライブラリーですか?
オラクルにつないでいます。
Actionのそのつど、コネクションを作成しています。
その作成の時に
Class.forName(this.getAAA().getItem("data-source", "", "db-driver"));
のようにリフレクションでドライバマネージャーを呼んでいます。

リフレクションがパーマネント領域に影響をあたえると
ネットでは出ていましたが、よくわかっていません。


ロードされていれば、必要に応じてロード済みのクラスを返すだけなので、
特に問題ありませんね。

雰囲気からすると、HibernateやらSpringやらの、
フレームワークやライブラリはつかってなさそうですね。

リクエストによって問題が起こるならば、
あちこちにあるアプリが全滅です。

ヒープのダンプを取得して、
アナライザで解析するしかなさそうですね。
DOON
会議室デビュー日: 2008/10/27
投稿数: 11
投稿日時: 2008-12-05 21:23
重ね重ねありがとうございます。

HibernateやらSpringは使ってないですね。

>リクエストによって問題が起こるならば、
>あちこちにあるアプリが全滅です。
これは、どういうことでしょうか?
セッションを使用していて解放していないとかだと
パーマネント領域も圧迫するのでしょうか?
もし、ご存知ならお願いします。

>ヒープのダンプを取得して、
>アナライザで解析するしかなさそうですね
そうですね。一応、JProbe(試用版)でも解析して、
ヒープ領域は大丈夫なのは確認しました。
GCViewerでもヒープは1GBのうち300MBぐらいしか使っていません。

パーマネント領域は非ヒープ領域だと
書いてあったので、悩んでいます。

引き続き調べます。

みなさん、ご存知でしたら引き続きよろしくお願いします。



かつのり
ぬし
会議室デビュー日: 2004/03/18
投稿数: 2015
お住まい・勤務地: 札幌
投稿日時: 2008-12-06 02:45
引用:

>リクエストによって問題が起こるならば、
>あちこちにあるアプリが全滅です。
これは、どういうことでしょうか?
セッションを使用していて解放していないとかだと
パーマネント領域も圧迫するのでしょうか?
もし、ご存知ならお願いします。


6秒おきにリクエスト飛ばしてるんですよね。
そんなのを提示されても原因なんてわかりませんよ。ということです。
セッションによって確保される領域はヒープです。

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