2011-07-07 10 views
1

私はNetbeans 6.9.1で作成したTomcat 6上で動作するWebアプリケーションを持ち、Entityクラスと永続性のためにウィザーズを使用しています。これは、Hibernate、データベースとしてのMySQL、15分ごとにタスクを実行するためのQuartz、およびJavaMailを使用します。Java OutOfMemory in Hibernate、Quartz and and JavaMail

次のように休止状態の設定は次のとおりです。

<?xml version="1.0" encoding="UTF-8" ?> 
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"> 
<persistence-unit name="GVPU" transaction-type="RESOURCE_LOCAL"> 
    <provider>org.hibernate.ejb.HibernatePersistence</provider> 
    <class>com.test.MyfirstEntity</class> 
    <class>com.test.MySecondEntity</class> 
    <exclude-unlisted-classes>true</exclude-unlisted-classes> 
<properties> 
    <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" /> 
    <property name="hibernate.connection.username" value="root" /> 
    <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" /> 
    <property name="hibernate.connection.password" value="password" /> 
    <property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/db" /> 
    <property name="hibernate.cache.provider_class" value="org.hibernate.cache.NoCacheProvider" /> 
    <property name="hibernate.hbm2ddl.auto" value="update" /> 
    <property name="hibernate.connection.provider_class" value="org.hibernate.connection.C3P0ConnectionProvider" /> 
    <property name="hibernate.c3p0.acquire_increment" value="1" /> 
    <property name="hibernate.c3p0.idle_test_period" value="300" /> 
    <property name="hibernate.c3p0.timeout" value="100" /> 
    <property name="hibernate.c3p0.max_size" value="100" /> 
    <property name="hibernate.c3p0.min_size" value="0" /> 
    <property name="hibernate.c3p0.max_statements" value="0" /> 
    </properties> 
    </persistence-unit> 
    </persistence> 

15分ごとに実行クォーツで作成したタスク、(IMAPで)のJavaMailを使用してGmailアカウントをチェックし、すべてのメッセージを取得し、プロセス彼ら(ルックスいくつかの情報について)、その情報を持つオブジェクトをHibernateを使用してDBに格納します。その後、すべてのメールを削除済みとしてマークするので、次の実行時には処理されません。

このタスクが実行されるたびに、処理するメールの数に応じて10,20,50MBを消費します。私はMySQL Administratorを見てきましたが、DB接続は必要ないときに閉じられます。しかし、私が(実行しているLinuxマシンの)プロセスメモリを見れば、CPU使用率が100%の限界に達するまでメモリが増加し、Tomcatはこれ以上応答しません。

さまざまな解決策を試すために、-Xms -XmxとPermGem Sizeを数回変更しましたが、システムが動作を停止してメモリが解放されていないポイントに常に到達します。

この問題をどこから見つけることができますか?私はJava VMに1.5GB以上の容量を割り当てました。また、1日以上経過してもハングアップします。

Tomcatとすべてのアプリケーションが動作を停止すると、スタックトレースはありません。

おかげ

答えて

0

一般的なアプローチ:メモリダンプを取得し、最も数多くのオブジェクトまたは最大のオブジェクトを探し、それらが存在してはならないかどうかを確認し、まだです。次に、このゴミがどのゴミを収集するのを妨げるオブジェクトが(ガーベージへの参照を保持することによって)確認できます。

2

JDKでjvisualvmを付けてメモリプロファイリングを取得します。

私の知る限り、JavaMailは大きな添付ファイルを効率的に処理できず、結果として得られるメールはさらに大きくなります。したがって、メールがメモリから消去されてから次のメールが処理されることを確認する必要があります。

ローカルのSMTPサーバーを設定することをお勧めします。これは、ほとんどのLinuxディストリビューションでは非常に簡単です。代わりに、Javaアプリケーションでそれを話せるようにしてください。これにより、タスクがはるかに速く完了し、メモリが解放されます。

OOMの例外が発生し続ける場合は、別のJVMでメールを送信することを検討して、アプリケーションの残りの部分に影響を与えないようにしてください。

0

プロセス実行間でHibernateセッションをどのように管理しますか?これまでのプロセスのすべてのキャッシュされたオブジェクトをHibernateのセッションキャッシュまたは自分のキャッシュに保持していないのは確かですか?

0

データベース接続を正しく終了していない可能性があります。これにより、オブジェクトがメモリ内に残り、ガーベッジ・コレクションが取得されなくなる可能性があります。放棄された接続を確認してログに記録します(c3p0設定で)。私はかつて同じような問題に遭遇し、それは悪意のあるデータベース接続に沸った。