2011-06-04 10 views
31

क्या मुझे इसे NewStringUTF() पर पास करने के बाद आवंटित स्ट्रिंग को मुक्त करना चाहिए?न्यूस्ट्रिंगटएफ() और फ्रीिंग मेमोरी

मैं कुछ करने के लिए इसी तरह के कोड है: मैं स्ट्रिंग यह NewStringUTF() को पास करने के बाद मुक्त कर जब

char* test; 
jstring j_test; 

test = some_function(); // <- malloc()s the memory 
j_test = (*env)->NewStringUTF(env, test); 

free(test); // <- should this be here? 

, मैं एक signal 11 (SIGSEGV), fault addr deadbaad त्रुटि मिलती है। अगर मैं free() कॉल को हटा देता हूं, तो त्रुटि गायब हो जाती है। मैं क्या गलत कर रहा हूं?

मुझे विवादित राय दिखाई देती हैं। कुछ कहते हैं कि मुझे इसे खुद मुक्त करना चाहिए, कुछ कहते हैं कि वीएम इसे मुक्त करता है, कुछ कहते हैं कि वीएम इसे मुक्त नहीं करता है और आपको इसे मुक्त करने के लिए अजीब वूडू जादू करना चाहिए। मैं उलझन में हूं। तो आप इसके free() करने की जरूरत है अगर आप malloc() साथ test आवंटित,:

+0

मेमोरी लीक से बचने के लिए जेएनआई फ्रीिंग मेमोरी का संभावित डुप्लिकेट] (http://stackoverflow.com/questions/1533378/jni-freeing-memory-to-avoid-memory-leak) – NPE

उत्तर

61

NewStringUTF() को const char* तर्क के लिए भंडारण पूरी तरह से आपकी जिम्मेदारी है। तो, आपके द्वारा पोस्ट किया गया स्निपेट सही है। आप कहीं और ढेर भ्रष्ट कर रहे हैं।

मुझे विवादित राय दिखाई देती हैं। कुछ कहते हैं कि मैं इसे स्वयं मुक्त कर सकता हूं, कुछ कहते हैं कि वीएम इसे मुक्त करता है, कुछ कहते हैं कि वीएम को मुक्त नहीं करता है और आपको इसे अजीब voodoo जादू मुक्त करना चाहिए। मैं उलझन में हूं।

वे jstring उदाहरण NewStringUTF() द्वारा लौटाए गए उदाहरण के बारे में बात कर रहे हैं। यह 'local references' के लिए भ्रमित नियमों का पालन करता है।

जब आप इसके साथ समाप्त हो जाते हैं तो DeleteLocalRef() के साथ इस संदर्भ को रिलीज़ करने में कभी भी त्रुटि नहीं होती है। हालांकि, यदि आप JVM थ्रेड के संदर्भ में NewStringUTF() पर कॉल करते हैं तो JVM कुछ संदिग्ध जादू करता है। जब मूल विधि जावा पर वापस आती है, तो किसी भी लीक किए गए स्थानीय संदर्भ स्वचालित रूप से साफ़ हो जाते हैं। इसलिए यदि आप सुनिश्चित हैं कि आपका अंतिम कॉलर जावा थ्रेड में है, तो आप संदर्भ को सुरक्षित रूप से रिसाव कर सकते हैं।

दूसरी तरफ, यदि आप मूल धागे के संदर्भ में चल रहे हैं - कहें, कुछ घटना रिपोर्टिंग थ्रेड जावा पर कॉलबैक बनाने के लिए - जावा पर कभी भी वापसी नहीं होती है, इसलिए आपको पर अपने jstring पर कॉल करना होगा (और वास्तव में सभी अन्य स्थानीय संदर्भ सामान्य जेएनआई कॉल द्वारा लौटाए गए हैं)।

+1

इंटेरस्टस्टिंग। अब मुझे पता है कि मेरा प्लॉबलेम कहां है। मुझे एक और लगातार जस्टिंग की जरूरत है। एक जो कचरा कलेक्टर का हिस्सा बन जाता है और केवल एक बार साफ हो जाने पर ही साफ हो जाता है। – Martin

+1

क्या कोई ऐसी स्थिति है जहां 'न्यूस्ट्रिंगटएफ()' के साथ प्राप्त 'jstring' पर' DeleteLocalRef() 'को कॉल करने के लिए असुरक्षित/गलत है? – namuol

+0

@namuol यदि आप बाद में जावा में jstring पास कर रहे हैं, तो आपको इसे अभी कभी नहीं हटा देना चाहिए। –

4

आपको केवल DeleteLocalRef() की आवश्यकता है, NewStringUTF() सिर्फ JVM पर malloc स्मृति है, जो JVM स्मृति का ख्याल रखेगा।

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