java.lang.OutOfMemoryError: जावा हीप स्पेस


96

मुझे मल्टी-थ्रेडिंग प्रोग्राम के निष्पादन में निम्नलिखित त्रुटि हो रही है

java.lang.OutOfMemoryError: Java heap space

उपरोक्त त्रुटि थ्रेड्स में से एक में हुई।

  1. मेरे ज्ञान तक, ढेर स्थान केवल उदाहरण चर द्वारा कब्जा कर लिया है। यदि यह सही है, तो ऑब्जेक्ट के निर्माण के समय स्पेस चर के रूप में कुछ समय के लिए ठीक चलने के बाद यह त्रुटि क्यों हुई।

  2. क्या ढेर के स्थान को बढ़ाने का कोई तरीका है?

  3. मुझे अपने कार्यक्रम में क्या बदलाव करने चाहिए ताकि यह कम जगह ले सके?


जवाबों:


104

यदि आप अपने ढेर स्थान को बढ़ाना चाहते हैं, तो आप java -Xms<initial heap size> -Xmx<maximum heap size>कमांड लाइन पर उपयोग कर सकते हैं । डिफ़ॉल्ट रूप से, मान JRE संस्करण और सिस्टम कॉन्फ़िगरेशन पर आधारित होते हैं। आप जावा वेबसाइट पर VM विकल्पों के बारे में अधिक जानकारी प्राप्त कर सकते हैं ।

हालाँकि, मैं आपके आवेदन को यह पता लगाने की सलाह दूंगा कि आपके ढेर का आकार क्यों खाया जा रहा है। NetBeans में इसके साथ शामिल एक बहुत अच्छा प्रोफाइलर है। मेरा मानना ​​है कि यह jvisualvmहुड के नीचे का उपयोग करता है । एक प्रोफाइलर के साथ, आप यह खोजने की कोशिश कर सकते हैं कि कई ऑब्जेक्ट्स कहाँ बनाए जा रहे हैं, जब ऑब्जेक्ट्स को कचरा इकट्ठा होता है, और बहुत कुछ।


1
मैं नेटबीन्स का उपयोग कर रहा हूं लेकिन मुझे पता नहीं है कि प्रोफाइलर का उपयोग कैसे किया जाता है। मैं प्रोफाइलर के बारे में अधिक जानना चाहूंगा ताकि मैं अपने एप्लिकेशन में मेमोरी लीक खोजने के लिए इसका उपयोग कर सकूं।
यतेंद्र गोयल

मैंने NetBeans साइट ( profiler.netbeans.org ) पर एक पृष्ठ पर एक लिंक जोड़ा , जिसमें बहुत मूल बातें से लेकर अधिक उन्नत उपयोग तक प्रोफ़ाइल के बारे में बहुत अच्छे दस्तावेज़ हैं।
थॉमस ओवेन्स

जावा संस्करणों के साथ डिफ़ॉल्ट मान बदलते हैं, इस जानकारी को अपने उत्तर में शामिल करना अच्छा होगा ।
डेरियस

बस इसी तरह की समस्या को ठीक किया और पहले कोशिश की: java -jar डिवीजन। इसलिए परमों का क्रम भी महत्वपूर्ण है।
हिपोकिटो

जार फ़ाइल के पास जार फ़ाइल के मुख्य () विधि के रूप में args []
Asu

29

1.- हां, लेकिन यह आपके प्रोग्राम द्वारा उपयोग की जाने वाली पूरी मेमोरी को बहुत अधिक संदर्भित करता है।

2.- हां जावा वीएम विकल्प देखें

-Xms<size>        set initial Java heap size
-Xmx<size>        set maximum Java heap size

अर्थात

java -Xmx2g अपने ऐप में अधिकतम 2 गीगाबाइट राम असाइन करें

लेकिन आपको यह देखना चाहिए कि क्या आपके पास पहले मेमोरी लीक नहीं है।

3.- यह प्रोग्राम पर निर्भर करता है। स्पॉट मेमोरी लीक का प्रयास करें। इस प्रश्न का उत्तर देना कठिन होगा। हाल ही में आप JConsole का उपयोग करके यह पता लगाने की कोशिश कर सकते हैं कि आपकी मेमोरी कहां जा रही है


जबकि (सच्चा);)
गाल ब्राचा

8

आप इस साइट को JVM में मेमोरी के बारे में अधिक जानने के लिए देखना चाह सकते हैं: http://developer.streamezzo.com/content/learn/articles/optimization-heap-memory-usage

मैंने यह देखने के लिए विजुअलगैक का उपयोग करना उपयोगी पाया है कि मेमोरी मॉडल के विभिन्न हिस्सों को कैसे भरना है, यह निर्धारित करने के लिए कि क्या बदलना है।

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

ठीक! मैं JVM को 1G RAM दूंगा।

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

यह निर्धारित करने के लिए कि मेमोरी रिसाव कहां हो सकता है, आप परीक्षण के पहले मेमोरी का परीक्षण करके और उसके बाद क्या है, के लिए यूनिट टेस्ट का उपयोग कर सकते हैं, और यदि कोई बहुत बड़ा बदलाव है तो आप इसकी जांच करना चाहते हैं, लेकिन, आपको इसकी आवश्यकता है आपका परीक्षण अभी भी चल रहा है, जबकि जाँच करें।


6

ढेर का आकार बढ़ाने के लिए आप जावा शुरू करते समय -Xmx तर्क का उपयोग कर सकते हैं; जैसे

-Xmx256M

6

आप नीचे दिए गए प्रोग्रेम के माध्यम से अपने ढेर स्मृति आकार प्राप्त कर सकते हैं।

public class GetHeapSize {
    public static void main(String[] args) {
        long heapsize = Runtime.getRuntime().totalMemory();
        System.out.println("heapsize is :: " + heapsize);
    }
} 

फिर तदनुसार आप हीप साइज़ को बढ़ा सकते हैं: java -Xmx2g http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html


6
  1. मेरे ज्ञान तक, ढेर स्थान केवल उदाहरण चर द्वारा कब्जा कर लिया है। यदि यह सही है, तो ऑब्जेक्ट के निर्माण के समय स्पेस चर के रूप में कुछ समय के लिए ठीक चलने के बाद यह त्रुटि क्यों हुई।

इसका मतलब है कि आप लगातार समय के साथ अपने आवेदन में अधिक वस्तुओं का निर्माण कर रहे हैं। नई वस्तुओं को ढेर मेमोरी में संग्रहीत किया जाएगा और यही ढेर मेमोरी में वृद्धि का कारण है।

ढेर न केवल उदाहरण चर होते हैं। यह सभी गैर-आदिम डेटा प्रकारों (ऑब्जेक्ट्स) को संग्रहीत करेगा। ये ऑब्जेक्ट्स लाइफ टाइम कम (मेथड ब्लॉक) या लॉन्ग हो सकते हैं (जब तक कि आपके आवेदन में ऑब्जेक्ट को संदर्भित नहीं किया जाता है)

  1. क्या ढेर के स्थान को बढ़ाने का कोई तरीका है?

हाँ। अधिक विवरण के लिए इस ओरेकल लेख पर एक नज़र डालें ।

ढेर का आकार निर्धारित करने के लिए दो मापदंड हैं:

-Xms:, जो प्रारंभिक और न्यूनतम हीप आकार निर्धारित करता है

-Xmx:, जो अधिकतम ढेर आकार निर्धारित करता है

  1. मुझे अपने कार्यक्रम में क्या बदलाव करने चाहिए ताकि यह कम जगह ले सके?

यह आपके आवेदन पर निर्भर करता है।

  1. अपने आवेदन की आवश्यकता के अनुसार अधिकतम ढेर मेमोरी सेट करें

  2. अपने एप्लिकेशन में मेमोरी लीक का कारण न बनें

  3. यदि आप अपने एप्लिकेशन में मेमोरी लीक पाते हैं, तो मूल कारण जैसे कि MAT , Visual VM , jconsole आदि की मदद से मूल कारण का पता लगाएं। एक बार जब आप मूल कारण को खोज लेते हैं, तो लीक को ठीक करें।

ओरेकल लेख से महत्वपूर्ण नोट्स

कारण: विस्तार संदेश जावा हीप स्पेस इंगित करता है कि ऑब्जेक्ट जावा हीप में आवंटित नहीं किया जा सकता है। यह त्रुटि जरूरी नहीं कि एक मेमोरी लीक है।

संभावित कारण:

  1. अनुचित विन्यास (पर्याप्त मेमोरी का आवंटन नहीं)
  2. आवेदन अनायास ही वस्तुओं के संदर्भ में है और यह वस्तुओं को कचरा एकत्र होने से रोकता है
  3. अनुप्रयोग जो फाइनल का अत्यधिक उपयोग करते हैं। यदि किसी वर्ग की अंतिम विधि होती है, तो उस प्रकार की वस्तुओं को कचरा संग्रहण के समय पुनः प्राप्त नहीं किया जाता है। यदि अंतिम सूत्र अंतिम पंक्ति के साथ नहीं रह सकता है, तो Java हीप भर सकता है और इस प्रकार का OutOfMemoryError अपवाद फेंक दिया जाएगा

एक अलग नोट पर, बेहतर कचरा संग्रह एल्गोरिदम ( CMS या G1GC ) का उपयोग करें

G1GC को समझने के लिए इस प्रश्न पर एक नज़र डालें


5
  1. अधिकांश मामलों में, कोड अनुकूलित नहीं है। उन वस्तुओं को छोड़ दें जिन्हें आपको लगता है कि आगे की आवश्यकता नहीं होगी। हर बार अपने पाश में वस्तुओं के निर्माण से बचें। कैश का उपयोग करने का प्रयास करें। मुझे नहीं पता कि आपका आवेदन कैसे हो रहा है। लेकिन प्रोग्रामिंग में, सामान्य जीवन का एक नियम भी लागू होता है

    रोकथाम इलाज से बेहतर है। "अनावश्यक वस्तुओं का निर्माण न करें"


3
  1. स्थानीय चर स्टैक पर स्थित हैं। हीप स्पेस ऑब्जेक्ट्स द्वारा कब्जा कर लिया जाता है।

  2. आप -Xmxविकल्प का उपयोग कर सकते हैं ।

  3. मूल रूप से हीप स्पेस का उपयोग हर उस समय किया जाता है जब आप किसी नई वस्तु को आवंटित करते हैं newऔर कुछ समय बाद मुक्त हो जाते हैं। इसलिए सुनिश्चित करें कि आप उन वस्तुओं का संदर्भ नहीं रखते हैं जिनकी आपको अब आवश्यकता नहीं है।


1

नहीं, मुझे लगता है कि आप स्टैक स्पेस के बारे में सोच रहे हैं। हीप स्पेस ऑब्जेक्ट्स द्वारा कब्जा कर लिया जाता है। इसे बढ़ाने का तरीका है -Xmx256m, कमांड लाइन पर आपकी ज़रूरत के हिसाब से 256 की जगह।


1

उस अपवाद से बचने के लिए, यदि आप ज्यूनिट और स्प्रिंग का उपयोग कर रहे हैं, तो इसे हर परीक्षण वर्ग में जोड़ने का प्रयास करें:

@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)

0

Netbeans में, 'Run' टूलबार पर जाएं, -> 'प्रोजेक्ट कॉन्फिगरेशन सेट करें' -> 'Customize' -> 'run' को इसके पॉप-अप विंडो -> 'VM Option' -> में भरें '-Xms2048m -Xmx2048m '। यह ढेर आकार की समस्या को हल कर सकता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.