java.lang.OutOfMemoryError: जीसी ओवरहेड सीमा पार हो गई




hashmap heap (11)

@takrl: इस विकल्प के लिए डिफ़ॉल्ट सेटिंग है:

java -XX:+UseConcMarkSweepGC

जिसका अर्थ है, यह विकल्प डिफ़ॉल्ट रूप से सक्रिय नहीं है। तो जब आप कहते हैं कि आपने " +XX:UseConcMarkSweepGC " विकल्प का उपयोग किया है, तो मुझे लगता है कि आप इस वाक्यविन्यास का उपयोग कर रहे थे:

java -XX:+UseConcMarkSweepGC

जिसका अर्थ है कि आप स्पष्ट रूप से इस विकल्प को सक्रिय कर रहे थे। इस document में Java HotSpot VM Options के सही वाक्यविन्यास और डिफ़ॉल्ट सेटिंग्स के लिए

मुझे यह त्रुटि एक प्रोग्राम में मिल रही है जो कई (सैकड़ों हजारों) हैश मैप ऑब्जेक्ट्स को कुछ (15-20) टेक्स्ट प्रविष्टियों के साथ बनाता है। डेटाबेस में सबमिट करने से पहले इन स्ट्रिंग्स को एकत्रित किया जाना चाहिए (छोटी मात्रा में तोड़ने के बिना)।

सूर्य के मुताबिक, त्रुटि होती है "अगर कचरा संग्रह में बहुत अधिक समय बिताया जा रहा है: यदि कुल समय का 98% से अधिक कचरा संग्रह में खर्च किया जाता है और ढेर के 2% से भी कम बरामद किया जाता है, तो आउटऑफमेमरी एरर फेंक दिया जाएगा। "।

जाहिर है, कोई भी JVM के लिए तर्क पारित करने के लिए कमांड लाइन का उपयोग कर सकता है

  • "-Xmx1024m" (या अधिक), या के माध्यम से, ढेर आकार में वृद्धि
  • "-XX: -UseGCOverheadLimit" के माध्यम से त्रुटि जांच को पूरी तरह से अक्षम करना।

पहला दृष्टिकोण ठीक काम करता है, दूसरा दूसरा java.lang.OutOfMemoryError में समाप्त होता है, इस बार ढेर के बारे में।

तो, प्रश्न: क्या विशेष उपयोग के मामले के लिए कोई प्रोग्रामेटिक विकल्प है (यानी, कई छोटे हैश मैप ऑब्जेक्ट्स)? यदि मैं हैश मैप स्पष्ट () विधि का उपयोग करता हूं, उदाहरण के लिए, समस्या दूर हो जाती है, लेकिन हैश मैप में संग्रहीत डेटा भी करें! :-)

स्टैक ओवरफ्लो में संबंधित विषय में इस मुद्दे पर भी चर्चा की गई है


अंत तक पहुंचने की प्रतीक्षा करते समय पूरी संरचना को स्मृति में संग्रहीत न करें।

इंटरमीडिएट परिणाम को हैशैप्स के बजाय डेटाबेस में एक अस्थायी तालिका में लिखें - कार्यात्मक रूप से, डेटाबेस तालिका हैशैप के समतुल्य है, यानी दोनों समर्थन डेटा तक पहुंच की कुंजी है, लेकिन तालिका मेमोरी बाध्य नहीं है, इसलिए यहां एक अनुक्रमित तालिका का उपयोग करें हैशपैप्स

यदि सही तरीके से किया जाता है, तो आपके एल्गोरिदम को परिवर्तन को भी ध्यान में नहीं रखना चाहिए - सही ढंग से यहां तालिका का प्रतिनिधित्व करने के लिए कक्षा का उपयोग करने का मतलब है, यहां तक ​​कि इसे एक हैशैप की तरह एक पुट (कुंजी, मान) और एक प्राप्त (कुंजी) विधि भी प्रदान करना है।

जब मध्यवर्ती तालिका पूर्ण हो जाती है, तो स्मृति से इसके बजाय आवश्यक एसक्यूएल कथन उत्पन्न करें।


इससे मुझे इस त्रुटि से छुटकारा पाने में मदद मिली। यह विकल्प अक्षम करता है -XX: + DisableExplicitGC


उम्म्म ... आपको या तो इसकी आवश्यकता होगी:

  1. पूरी तरह से अपने एल्गोरिदम और डेटा-संरचनाओं पर पुनर्विचार करें, जैसे कि इन सभी छोटे हैश मैप्स की आवश्यकता नहीं है।

  2. एक मुखौटा बनाएं जो आपको आवश्यकतानुसार स्मृति के उन हैश मैप्स को इन-आउट-आउट करने की अनुमति देता है। एक साधारण एलआरयू-कैश सिर्फ टिकट हो सकता है।

  3. जेवीएम के लिए उपलब्ध स्मृति ऊपर। यदि आवश्यक हो, तो यहां तक ​​कि अधिक रैम खरीदना सबसे तेज़, CHEAPEST समाधान हो सकता है, यदि आपके पास इस जानवर को होस्ट करने वाली मशीन का प्रबंधन है। ऐसा कहकर कि: मैं आम तौर पर "इसमें अधिक हार्डवेयर फेंकने" के प्रशंसक नहीं हूं, विशेष रूप से यदि एक वैकल्पिक एल्गोरिदमिक समाधान उचित समय सीमा के भीतर सोचा जा सकता है। यदि आप इन समस्याओं में से प्रत्येक पर अधिक हार्डवेयर फेंकते रहते हैं तो आप जल्द ही रिटर्न कम करने के कानून में भाग लेते हैं।

आप वास्तव में क्या करने की कोशिश कर रहे हैं? मुझे संदेह है कि आपकी वास्तविक समस्या का बेहतर दृष्टिकोण है।


ग्रहण MAT या VisualVM जैसे प्रोफ़ाइल टूल की सहायता से अपने एप्लिकेशन में मेमोरी लीक को ठीक करें

G1GC या बाद के संस्करणों के साथ, जी 1 जीसी का उपयोग G1GC , जो अन्य जीसी एल्गोरिदम में 2% के विपरीत कचरा संग्रह पर 10% खर्च करता है।

-Xms1g -Xmx2g साथ हीप मेमोरी सेट करने के अलावा, 'कोशिश करें

-XX:+UseG1GC 
-XX:G1HeapRegionSize=n, 
-XX:MaxGCPauseMillis=m, 
-XX:ParallelGCThreads=n, 
-XX:ConcGCThreads=n`

इन मानकों को ठीक-ठीक करने के लिए oracle आलेख देखें।

एसई में जी 1 जीसी से संबंधित कुछ सवाल:

जावा 7 (जेडीके 7) कचरा संग्रह और दस्तावेज जी 1 पर

उत्पादन में जावा जी 1 कचरा संग्रह

आक्रामक कचरा कलेक्टर रणनीति


त्रुटि के मामले में:

"आंतरिक कंपाइलर त्रुटि: java.lang.OutOfMemoryError: जीसी ओवरहेड सीमा java.lang.AbstractStringBuilder पर पार हो गई"

जावा ढेर अंतरिक्ष को 2 जीबी यानी, -Xmx2g.


प्रक्रिया को आसानी से चलाने के लिए आप अनिवार्य रूप से स्मृति से बाहर निकल रहे हैं। विकल्प जो दिमाग में आते हैं:

  1. जैसा कि आपने उल्लेख किया है, उतनी मेमोरी निर्दिष्ट करें, पहले -Xmx512m जैसे कुछ के बीच प्रयास करें
  2. HashMap ऑब्जेक्ट्स के छोटे बैचों के साथ काम करें, यदि संभव हो तो एक बार प्रक्रिया करें
  3. यदि आपके पास बहुत सारे डुप्लिकेट स्ट्रिंग हैं, तो उन्हें String.intern() में डालने से पहले String.intern() उपयोग करें
  4. अपने मामले के लिए ट्यून करने के लिए HashMap(int initialCapacity, float loadFactor) कन्स्ट्रक्टर का उपयोग करें

मेरे मामले के लिए -Xmx विकल्प का उपयोग कर स्मृति में वृद्धि समाधान था।

मेरे पास जावा में 10 जी फ़ाइल पढ़ी गई थी और हर बार मुझे एक ही त्रुटि मिली। ऐसा तब हुआ जब top आदेश में RES स्तंभ में मान -Xmx विकल्प में मान सेट पर पहुंच गया। फिर -Xmx विकल्प का उपयोग कर स्मृति को बढ़ाकर सब ठीक हो गया।

एक और बिंदु भी था। जब मैं अपने उपयोगकर्ता खाते में JAVA_OPTS या CATALINA_OPTS सेट करता हूं और फिर स्मृति की मात्रा में वृद्धि करता हूं तो मुझे एक ही त्रुटि मिलती है। फिर, मैंने अपने कोड में उन पर्यावरण चर के मान मुद्रित किए जो मुझे सेट किए गए अनुसार अलग-अलग मान देते थे। इसका कारण यह था कि टोमकैट उस प्रक्रिया के लिए जड़ था और फिर जब मैं एक सूअर नहीं था, तो मैंने व्यवस्थापक से catalina.sh में catalina.sh में स्मृति को बढ़ाने के लिए कहा।


यदि आपके पास जावा 8 है , और आप जी 1 कचरा कलेक्टर का उपयोग कर सकते हैं, तो अपने आवेदन को इसके साथ चलाएं:

 -XX:+UseG1GC -XX:+UseStringDeduplication

यह जी 1 को समान स्ट्रिंग ढूंढने के लिए कहता है और उनमें से केवल स्मृति में ही रहता है, और अन्य स्मृति में उस स्ट्रिंग के लिए केवल एक सूचक हैं।

यह तब उपयोगी होता है जब आपके पास बहुत बार दोहराया जाता है। यह समाधान काम कर सकता है या नहीं और प्रत्येक एप्लिकेशन पर निर्भर करता है।

अधिक जानकारी:
https://blog.codecentric.de/en/2014/08/string-deduplication-new-feature-java-8-update-20-2/ http://java-performance.info/java-string-deduplication/


रिकॉर्ड के लिए, आज हमें एक ही समस्या थी। हमने इसे इस विकल्प का उपयोग करके तय किया है:

-XX:-UseConcMarkSweepGC

जाहिर है, इसने कचरा संग्रह के लिए उपयोग की जाने वाली रणनीति को संशोधित किया, जिसने मुद्दा गायब कर दिया।


समांतर कलेक्टर कचरा संग्रह में बहुत अधिक समय खर्च होने पर OutOfMemoryError फेंक देगा। विशेष रूप से, यदि कुल समय का 98% से अधिक कचरा संग्रह में खर्च किया जाता है और ढेर के 2% से भी कम बरामद किया जाता है, तो OutOfMemoryError फेंक दिया जाएगा। यह सुविधा कम या कोई प्रगति करते समय अनुप्रयोगों को विस्तारित अवधि के लिए चलने से रोकने के लिए डिज़ाइन की गई है क्योंकि ढेर बहुत छोटा है। यदि आवश्यक हो, तो इस सुविधा को विकल्प -XX:-UseGCOverheadLimit को कमांड लाइन में जोड़कर अक्षम किया जा सकता है।





g1gc