जहां मैं काम करता हूं, हम अपने अनुप्रयोगों में से एक में हेप-स्पेस से बाहर चल रहे JVM के साथ समस्याएं अनुभव कर रहे हैं। मैंने कुछ इस कारण के लिए खोज की है, जिसमें एक प्रोफाइलर के साथ एक हीप-डंप को देखकर, लेकिन अब मैं काफी अटक गया हूं।हाइबरनेट, सत्र फैक्ट्रीऑब्जेक्ट फैक्ट्री और आउटऑफमेमरी एरर: जावा हीप स्पेस
सबसे पहले, सिस्टम में सवाल के बारे में थोड़ा सा: यह संगठनों के बारे में रिकॉर्ड रखने के लिए स्प्रिंग और हाइबरनेट का उपयोग कर जावा एप्लिकेशन है। यह प्रणाली webservice क्लाइंट्स के एक सेट से बना है जिसका उपयोग इस प्रकार के डेटा के लिए जिम्मेदार सरकारी संस्थान के संगठनों के बारे में डेटा पुनर्प्राप्त करने के लिए किया जाता है। इसके अतिरिक्त, सिस्टम ऐसे डेटा के साथ एक स्थानीय डेटाबेस रखता है, जो webservice कॉल के लिए कैश के रूप में कार्य करता है, ताकि किसी संगठन के बारे में पहली बार जानकारी का अनुरोध किया जा सके, यह स्थानीय संबंधपरक डेटाबेस में सहेजा गया है, और इसका उपयोग पुनर्प्राप्ति के लिए किया जाता है निम्नलिखित अनुरोधों के लिए डेटा का। इस डेटाबेस के साथ संचार के लिए हाइबरनेट का उपयोग किया जाता है।
समस्या, जैसा कि पहले संकेत दिया गया है, यह है कि समय के बाद, एप्लिकेशन OutOfMemoryError: जावा हीप स्पेस के साथ क्रैश हो रहा है। मैंने ग्रहण + मैट का उपयोग करके एक हीप-डंप को देखा है, और अपराधियों को हाइबरनेट के सत्र के रूप में पहचाना है फैक्ट्रीऑब्जेक्ट फैक्ट्री, आवंटित स्मृति का लगभग 85% (इसे सभी याद रखने वाली स्मृति) लेते हैं। मुझे यह पता लगाने में थोड़ा मुश्किल लगा है कि इस प्रकार किस प्रकार की वस्तुओं को रखा जाता है। शीर्ष स्तर पर ग्लासफ़िश WebappClassLoader है, जिसमें org.hibernate.impl.SessionFactoryObjectFactory शामिल है। इसमें एक org.hibernate.util.FastHashMap है, जो बदले में java.util.HashMap है। इसमें कई प्रविष्टियां हैं, जिनमें से प्रत्येक में हैश मैप-एंट्री, एक org.hibernate.impl.SessionFactoryImpl और एक स्ट्रिंग शामिल है। बदले में हैश मैप-एंट्री में एक ही तीन ऑब्जेक्ट्स, हैश मैप-एंट्री, एक सत्र फैक्ट्रीआईएमपीएल और स्ट्रिंग शामिल है, और यह संरचना कई बार खुद को दोहराती है। सत्र फ़ैक्टरीइम्पल्स में कई ऑब्जेक्ट्स हैं, विशेष रूप से org.hibernate.persister.entity.SingleTableEntityPersister, जिसमें कई स्ट्रिंग्स और हैश मैप्स शामिल हैं। कुछ स्ट्रिंग्स डोमेन ऑब्जेक्ट्स में वेरिएबल्स को संदर्भित करती हैं, और कुछ में SQL-स्टेटमेंट होते हैं।
यह पहली नज़र में लग रहा था कि यह ऑब्जेक्ट स्मृति की असीमित मात्रा ले रहा था (डंप-फ़ाइल 800 एमबी थी, जिसमें से 650 एमबी सत्र फ़ैक्टरीऑब्जेक्ट फैक्ट्री द्वारा कब्जा कर लिया गया था), इसलिए मैंने ऑब्जेक्ट लोडिंग और अनलोडिंग के लॉगिंग को सक्षम किया, और पूछने की कोशिश की किसी संगठन के बारे में डेटा के लिए सिस्टम (किसी अन्य सिस्टम से एक webservice कॉल के माध्यम से)। मैंने जो देखा वह यह था कि वस्तुओं को लोड करने के लिए बहुत सारे संदेश थे, लेकिन अनलोड किए गए ऑब्जेक्ट्स के बारे में बहुत कम (केवल वे लोग जो लाइब्रेरी ऑब्जेक्ट्स को उतार रहे थे)। इससे मेरा मानना है कि एक बार ऑब्जेक्ट (एक संगठन कहें) स्मृति में लोड हो गया था, यह कभी भी अनलोड नहीं होता है, जिसका मतलब है कि समय के साथ, सिस्टम स्मृति से बाहर हो जाएगा। (क्या यह लॉग में मिली चीज़ों के आधार पर एक उचित धारणा है?)
फिर, मैंने इसका कारण खोजने की कोशिश की, लेकिन यह बहुत कठिन था। जैसे ही हाइबरनेट द्वारा लोड की गई वस्तुएं तब तक रहेंगी जब तक उनका सत्र रहता है, मैंने स्प्रिंग्स के हाइबरनेटडेटो सपोर्ट # getSession() को कॉल को प्रतिस्थापित करके, सत्रों को संभालने के तरीके को बदलने की कोशिश की, HibernateDaoSupport # getSessionFactory()। GetCurrentSession()। इस समस्या पर कोई प्रभावशाली प्रभाव नहीं पड़ा। मैंने कॉल में कुछ डाओ-विधियों के आखिरकार ब्लॉक में getCurrentSession()। Flush() और .clear() को कॉल जोड़ने का भी प्रयास किया, बिना किसी प्रभावशाली प्रभाव के। (दाओ-विधियों को सभी @ ट्रांसेक्शनल के साथ एनोटेटेड किया गया है, जिसका अर्थ यह होना चाहिए कि सत्र केवल ट्रांजैक्शनल-विधि के भीतर ही जीवित होना चाहिए, और विधि को लगातार कॉल करने के लिए अलग-अलग सत्र प्राप्त करना चाहिए जब getCurrentSession() (?))
तो, अब जब मैं जांच के लिए अन्य क्षेत्रों के साथ आने की बात आती हूं तो मैं काफी अटक गया हूं। क्या किसी के पास कोई विचार या कुछ पॉइंटर है कि कहां देखना है और क्या देखना है?
ढेर-डंप ने दिखाया कि org.hibernate.impl.SessionFactoryImpl के कई उदाहरण हैं, क्या यह अपेक्षित है? (मैंने सोचा होगा कि केवल सत्र कारखाना, या कुछ शीर्ष का एक उदाहरण होना चाहिए।)
कोई जवाब के लिए अग्रिम धन्यवाद।
सादर,
Tobb
संपादित करें:
मुझे लगता है कि मैं वास्तव में समस्या को हल करने mananged है:
ऐसा नहीं है कि जिस तरह से अन्य वस्तुओं के लिए उनकी निर्भरता में संचालन हुआ निकला webservice-classesस समस्या थी। यह webservice कक्षाओं के निर्माता में नए ClassPathXmlAplicationContext (...) को कॉल करके हल किया गया था। इससे प्रत्येक अनुरोध (या कम से कम प्रत्येक सत्र) के लिए बहुत सारी वस्तुओं को लोड किया जा रहा था, जिन्हें फिर से अनलोड नहीं किया गया था (मुख्य रूप से हाइबरनेट का सत्र फ़ैक्टरीइम्पल)। मैंने webservice-classesर्थों को बदल दिया है, इसलिए वे इसके निर्भरता को इंजेक्ट करते हैं, और जो मैंने अब तक प्रोफाइलर्स का उपयोग करके देखा है, कई सत्र FactoryImpl-ऑब्जेक्ट्स के साथ समस्या हल हो गई है।
मुझे लगता है कि समस्या हो सकती है ग्लासफिश 3.x के लिए ग्लासफिश 2.x से उन्नयन से बदतर कर दिया है, कैसे वेब सेवा वर्गों instantiated कर रहे हैं के रूप में कुछ मतभेद हो सकता है।
वैकल्पिक रूप से स्थिर कारखाने के लिए, मुझे लगता है कि 'ClassPathXmlApplicationContext' एक' close'-विधि है कि हो सकता है इस समस्या से बचने के लिए बुलाया। – Tobb