Spring、Hibernate、および JPA を使用する Web アプリケーションで問題が発生しています。問題は、時間の経過とともに増加し、決して減少しないように見える非常に高いメモリ消費です。これらは、EntityManager の不適切な使用に起因する可能性が最も高いです。私は周りを検索しましたが、確かなものはまだ見つかりません。
唯一の EntityManager が注入される次の GenericDAO をすべて拡張する DAO を使用しています。
public abstract class GenericDAOImpl<E extends AbstractEntity<P>, P> implements
GenericDAO<E, P> {
@PersistenceContext
@Autowired
private EntityManager entityManager;
[...]
汎用 DAO が使用されるのは、ID などでエンティティを取得するメソッドがあり、40 個までのすべての DAO に実装するのが面倒だからです。
EntityManager は、次の方法で Spring Bean として構成されます。
<bean class="org.springframework.orm.jpa.JpaTransactionManager"
id="transactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<tx:annotation-driven mode="aspectj"
transaction-manager="transactionManager" />
<bean
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
id="entityManagerFactory">
<property name="persistenceUnitName" value="persistenceUnit" />
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="entityManager" factory-bean="entityManagerFactory"
factory-method="createEntityManager" scope="singleton" />
私が考える最大の問題は、この共有 EntityManager をすべてに使用することです。サービス クラスでは、トランザクションを必要とするメソッドに @Transactional アノテーションを使用しています。これは、読み取ったものから EntityManager を自動的にフラッシュしますが、クリアとは異なるため、オブジェクトはまだメモリ内にあると思います。
毎日発生する DB へのデータの自動インポートのたびに、メモリが増加していることに気付きました (それぞれ 25,000 行の最大 7 ファイルで、多数のリンク オブジェクトが作成されます)。しかし、通常の機能中、大量のデータを取得するとき (リクエストに対して一度に 100 ~ 200 個のオブジェクトとしましょう) も同様です。
現在の状況を改善する方法を知っている人はいますか (現時点ではちょっと悪いので...)。
編集:デプロイされたアプリでプロファイラーを実行しましたが、これが見つかりました:
One instance of "org.hibernate.impl.SessionFactoryImpl" loaded by "org.apache.catalina.loader.WebappClassLoader @ 0xc3217298" occupies 15,256,880 (20.57%) bytes. The memory is accumulated in one instance of "org.hibernate.impl.SessionFactoryImpl" loaded by "org.apache.catalina.loader.WebappClassLoader @ 0xc3217298".
これはおそらく EntityManager がクリアされていないのでしょうか?