2012-04-17 15 views
8

मुझे अपने आवेदन के एक नए संस्करण में दैनिक आउटऑफमेमरी त्रुटियां मिल रही हैं। हमारे पास टोमकैट के लिए आवंटित 1.5 जीबी ढेर है।जेपीए हाइबरनेट डीबीसीपी टॉमकैट आउटऑफमेमरी

ग्रहण मेमोरी विश्लेषक (http://www.eclipse.org/mat/) का उपयोग करना मैं सबसे छोटा संचय पथ के अंतर्गत निम्नलिखित

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 

इस के आगे निरीक्षण डुप्लिकेट श्रृंखलाएं जिनमें हाइबरनेट क्वेरी दी गई हैं की एक बहुत कुछ पता चलता मिला है। मेरे अनुप्रयोगों की होम स्क्रीन पर, मैं दस्तावेज़ों की एक सूची लोड करता हूं। ढेर डंप में क्वेरी का डुप्लिकेट 8,241 बार मौजूद है।

मैंने यह भी देखा कि 1 जीबी ढेर org.apache.tomcat.dbcp.dbcp.AbandonedObjectPool में निहित है। यह दस्तावेज़ क्वेरी दस्तावेज़ बाइनरी डेटा लोड कर रहा था। यह दस्तावेज़ जो लोड हो रहा है वह लगभग 1 एमबी है। इससे मुझे संदेह होता है कि सूची कचरा कलेक्टर द्वारा साफ नहीं हो रही है। हम क्वेरी से अनावश्यक डेटा निकाल देंगे लेकिन यह अभी भी मुझसे चिंतित है कि वस्तुएं चारों ओर चिपक रही हैं।

मैं जेपीए, हाइबरनेट और स्प्रिंग का उपयोग कर रहा हूं। मैं उस दस्तावेज़ पर @Transactional(readOnly=true) का उपयोग कर रहा हूं जो दस्तावेज़ सूची प्राप्त करता है। यहां डेटा स्रोत के लिए मेरी स्प्रिंग कॉन्फ़िगरेशन है:

<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> 

मैं कनेक्शन पूलिंग प्रदान करने के लिए टोमकैट का उपयोग कर रहा हूं। यहां मेरी कॉन्फ़िगरेशन है:

<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"/> 

सेवा परत में @ ट्रान्सैक्शनल है। मेरे जेपीए क्वेरी इस तरह दिखता है:

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; 
    } 

मैं स्मृति रिसाव के मूल कारण की पहचान करने में मदद करने के लिए क्या करना चाहिए? क्या कोई डीबीसीपी, हाइबरनेट या स्प्रिंग सेटिंग्स है जो इसमें योगदान दे सकती है? क्या जेपीए क्वेरी कोड में आप जो कुछ भी देखते हैं, वह योगदान दे सकता है?

+0

getEntityManager() को कैसे कार्यान्वित किया जाता है? EntityManager एनोटेशन @PersistenceContext के साथ इंजेक्शन दिया गया है? – samlewis

+0

हां। वसंत इंजेक्शन कर रहा है, यह जावाईई सर्वर में नहीं चल रहा है। हम टोमकैट का उपयोग कर रहे हैं। – Allan

उत्तर

0

विधि से वापस आने से पहले EntityManager कैश को साफ़ करने का प्रयास करें। पहले EntityManager.flush() विधि को कॉल करें और फिर साफ़ करें()। यह आपकी सहायता कर सकता है यदि आपका EntityManager लंबे समय तक "रहता है" और इसका उपयोग कई डेटाबेस संचालनों द्वारा किया जाता है।

यदि आप वसंत का उपयोग करते हैं तो आप समस्याग्रस्त स्थिति के लिए हाइबरनेट का उपयोग करके छोड़ सकते हैं और सादे जेडीबीसी के साथ जा सकते हैं। वसंत हमें जेडीबीसीटीप्लेट को प्रश्नों के साथ आसानी से काम करने देता है और सामान्य लेनदेन प्रबंधन इंटरफ़ेस भी प्रदान करता है, ताकि आप जेडीबीसी प्रश्नों के साथ हाइबरनेट ऑपरेशंस को मिश्रित कर सकें।

1

मैं लीक की पहचान के लिए VisualVM या jProfiler का उपयोग करने की दृढ़ता से अनुशंसा करता हूं। इसका आईएमएचओ सबसे आसान तरीका है।

संबंधित मुद्दे