Tôi nhận được lỗi OutOfMemory hàng ngày trong một phiên bản mới của đơn đăng ký của mình. Chúng tôi có 1,5 GB đống phân bổ cho Tomcat.JPA Hibernate DBCP Tomcat OutOfMemory
Sử dụng máy phân tích Memory Eclipse (http://www.eclipse.org/mat/) Tôi đã nhận như sau dưới Luỹ kế Shortest Path
org.apache.tomcat.dbcp.pool.impl.CursorableLinkedList$Listable @ 0xa1566cc8
_head org.apache.tomcat.dbcp.pool.impl.CursorableLinkedList @ 0xa1566ca8
_pool org.apache.tomcat.dbcp.dbcp.AbandonedObjectPool @ 0xa1566c38
connectionPool org.apache.tomcat.dbcp.dbcp.BasicDataSource @ 0xa1566980
dataSource org.springframework.orm.jpa.JpaTransactionManager @ 0xa0b01760
<Java Local> java.lang.Thread @ 0xa4005900 ajp-8141-5 Thread
kiểm tra sâu hơn về điều này cho thấy rất nhiều các chuỗi trùng lặp đó là các truy vấn Hibernate. Trên màn hình chính của ứng dụng của tôi, tôi tải danh sách tài liệu. Một bản sao của truy vấn tồn tại 8,241 lần trong bãi chứa đống.
Tôi cũng nhận thấy rằng 1 GB đống được chứa trong org.apache.tomcat.dbcp.dbcp.AbandonedObjectPool. Truy vấn tài liệu này đang tải dữ liệu nhị phân tài liệu. Tài liệu đang tải khoảng 1MB. Điều này làm cho tôi nghi ngờ rằng Danh sách không được dọn dẹp bởi bộ thu gom rác. Chúng tôi sẽ loại bỏ dữ liệu không cần thiết khỏi truy vấn nhưng nó vẫn lo ngại rằng các đối tượng đang bám sát.
Tôi đang sử dụng JPA, Hibernate và Spring. Tôi đang sử dụng @Transactional(readOnly=true)
trên phương thức nhận danh sách tài liệu. Đây là cấu hình Spring của tôi cho nguồn dữ liệu:
<jee:jndi-lookup jndi-name="jdbc/MyDB" id="myDataSource"/>
<bean id="myEmf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="myDataSource"/>
<property name="persistenceUnitName" value="WebPU"/>
<property name="persistenceProvider">
<bean class="org.hibernate.ejb.HibernatePersistence" />
</property>
<property name="jpaVendorAdapter">
<bean
class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="database" value="SQL_SERVER" />
<property name="showSql" value="false" />
<property name="generateDdl" value="false" />
</bean>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="myEmf" />
</bean>
Tôi đang sử dụng Tomcat để cung cấp kết nối tổng hợp. Đây là cấu hình của tôi:
<Resource auth="Container" driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver" initialSize="20"
logAbandoned="true" maxActive="100" maxIdle="30" maxWait="10000" name="jdbc/MyDB" password="pass" poolPreparedStatements="true" removeAbandoned="true" removeAbandonedTimeout="30"
type="javax.sql.DataSource"
url="jdbc:sqlserver://devmssql;databaseName=MY_DEV;responseBuffering=adaptive;port=1444"
username="user"/>
Lớp dịch vụ có @Transactional. Truy vấn JPA của tôi trông giống như sau:
public List<Document> getDocs(int cId, int lId, int ldId) {
CriteriaBuilder queryBuilder = getEntityManager().getCriteriaBuilder();
CriteriaQuery<Document> select = queryBuilder.createQuery(Document.class);
Root<Document> from = select.from(Document.class);
select.where(
queryBuilder.and(queryBuilder.equal(from.get(Document_.cId), cId),
queryBuilder.equal(from.get(Document_.lId), lId),
queryBuilder.equal(from.get(Document_.ldId), ldId)));
TypedQuery<Document> tq = getEntityManager().createQuery(select);
final List<Document> rl = tq.getResultList();
return rl;
}
Tôi nên tìm gì để giúp xác định nguyên nhân gốc rễ của rò rỉ bộ nhớ? Có các cài đặt DBCP, Hibernate hoặc Spring có thể đóng góp cho điều này không? Có bất kỳ điều gì bạn nhận thấy trong mã truy vấn JPA có thể đang đóng góp không?
getEntityManager() được triển khai như thế nào? EntityManager được tiêm với chú thích @PersistenceContext? – samlewis
Có. Mùa xuân đang tiêm, điều này không chạy trong một máy chủ JavaEE. Chúng tôi đang sử dụng Tomcat. – Allan