J2ObjC मेमोरी मॉडल

इस दस्तावेज़ में बताया गया है कि J2ObjC अनुवाद किए गए कोड के तहत मेमोरी को कैसे मैनेज किया जाता है और शेयर की गई मेमोरी को ऐक्सेस करते समय प्रोग्राम कैसे काम करते हैं.

मेमोरी प्रबंधन

J2ObjC का एक लक्ष्य अनुवाद किया गया कोड बनाना है, जो Objective-C के रेफ़रंस गिनती के माहौल में आसानी से इंटिग्रेट हो जाएगा. इससे अनुवाद किए गए Java कोड का इस्तेमाल, नेटिव तौर पर लिखे गए ऑब्जेक्टिव-सी के तौर पर करने में आसान हो जाता है, क्योंकि Java और ऑब्जेक्टिव-सी एनवायरमेंट के बीच पास किए जा रहे ऑब्जेक्ट के मालिकाना हक को ट्रांसफ़र करना आसान नहीं होता.

Java, मेमोरी मैनेजमेंट के लिए गार्बेज कलेक्शन का इस्तेमाल करता है. इसलिए, Java कोड में अपने ऑब्जेक्ट के लिए, साफ़ तौर पर कोई मेमोरी मैनेजमेंट नहीं होता. इसलिए, J2ObjC को सही तरीके से रेफ़रंस काउंटिंग कॉल शामिल करना चाहिए, ताकि यह पक्का किया जा सके कि ऑब्जेक्ट सही समय पर लिस्ट किए गए हैं. हमने नियमों के इन सेट को तय किया है जो परफ़ॉर्मेंस को बेहतर और व्यावहारिक दोनों मानते हैं:

  • सभी ऑब्जेक्ट, अपने-आप रिलीज़ होने वाले मौजूदा पूल के कम से कम समय तक लाइव रहेंगे.
    • इस सामान्य नियम की मदद से, हम ऐसे बहुत से रखरखाव और रिलीज़ को छोड़ सकते हैं जिनके लिए ऐसा करना ज़रूरी नहीं होता.
  • लोकल वैरिएबल को सेव नहीं किया जाता.
    • लोकल वैरिएबल के रीड या राइट पर कॉल की गिनती करने वाला कोई रेफ़रंस नहीं है.
  • फ़ील्ड बनाए रखे जाते हैं.
    • फ़ील्ड कॉल का असाइनमेंट, नई वैल्यू पर बना रहता है और पुरानी वैल्यू पर अपने-आप रिलीज़ हो जाता है.
  • नए ऑब्जेक्ट तुरंत अपने-आप रिलीज़ हो जाते हैं. (जब तक कि तुरंत किसी फ़ील्ड को असाइन न कर दिया जाए)

रेफ़रंस साइकल

रेफ़रंस साइकल तब मौजूद होता है, जब कोई ऑब्जेक्ट अपने फ़ील्ड के ज़रिए, सीधे तौर पर या किसी दूसरे तरीके से अपने बारे में बताता है. रेफ़रंस साइकल को Java के कूड़े कलेक्शन के ज़रिए साफ़ किया जा सकता है, लेकिन इससे ऑब्जेक्टिव-सी के रेफ़रंस के लिए गिनती के माहौल में मेमोरी लीक हो जाएगी. रेफ़रंस साइकल को रोकने का कोई ऑटोमेटेड तरीका नहीं है. हालांकि, हम Cycle Finder टूल उपलब्ध कराते हैं, जिससे साइकल की अपने-आप पहचान की जा सकती है. रेफ़रंस साइकल को ठीक करने के कुछ सामान्य तरीके यहां दिए गए हैं:

  • किसी एक रेफ़रंस को कमज़ोर करने के लिए, @Weak या @WeakOuter की व्याख्या जोड़ें.
  • किसी एक ऑब्जेक्ट में cleanup() तरीका जोड़ें, जो कुछ फ़ील्ड को शून्य पर सेट करता है. ऑब्जेक्ट को खारिज करने से पहले cleanup() को कॉल करें.
  • कोड को फिर से डिज़ाइन करें, ताकि रेफ़रंस साइकल बनाने से पूरी तरह बचा जा सके.

शेयर मेमोरी

मल्टी-थ्रेड प्रोग्राम में, कुछ डेटा को एक से ज़्यादा थ्रेड के ज़रिए शेयर किया जा सकता है. Java कई टूल उपलब्ध कराता है, जिनकी मदद से शेयर किए गए डेटा को थ्रेड-सुरक्षित ऐक्सेस किया जा सकता है. इस सेक्शन में, शेयर किए गए डेटा को ऐक्सेस करने के लिए J2ObjC की सुविधा के बारे में जानकारी दी गई है.

सिंक किया गया

J2ObjC, synchronized कीवर्ड को सीधे ऑब्जेक्टिव-सी @synchronized से मैप करता है.

ऐटॉमिकिटी

Java long और double को छोड़कर, सभी तरह के स्टोर और लोड के लिए अलग-अलग तरह की सुविधाएं देता है. JLS-17.7 देखें. volatile फ़ील्ड (इसके बारे में नीचे बताया गया है) को छोड़कर, J2ObjC यह पक्का करने के लिए कोई खास तरीका नहीं बताता कि परमाणु लोड और स्टोर हों. इससे यह जानकारी मिलती है:

  • सभी iOS प्लैटफ़ॉर्म 32 या 64-बिट वाले होते हैं, इसलिए long और double को छोड़कर, प्रीमिटिव टाइप के स्टोर और लोड, 32-बिट वाले डिवाइसों पर ऐटॉमिक होते हैं. साथ ही, 64-बिट सिस्टम पर सभी ऐटॉमिक होते हैं.
  • J2ObjC में, ऑब्जेक्ट टाइप के लोड और स्टोर ऐटॉमिक नहीं हैं.
    • रेफ़रंस की संख्या को ऐटम रूप से अपडेट करना बहुत महंगा होता है.
    • किसी ऑब्जेक्ट फ़ील्ड को volatile एलान करके ऐटॉमिक बनाया जा सकता है. (नीचे देखें)

वोलाटाइल फ़ील्ड

volatile फ़ील्ड के लिए, Java एक-दूसरे से बिलकुल अलग और क्रम में एक जैसा क्रम (JLS-8.3.1.4) देता है. इसका इस्तेमाल सिंक करने के लिए किया जा सकता है. J2ObjC, सभी volatile फ़ील्ड के लिए Java की तरह की गारंटी देता है. J2ObjC, volatile फ़ील्ड के लिए नीचे दिए गए तरीके इस्तेमाल करता है:

  • प्रिमिटिव टाइप को c11 ऐटॉमिक टाइप के लिए मैप किया जाता है.
    • जैसे volatile int -> _Atomic(jint)
  • ऑब्जेक्ट फ़ील्ड को pथ्रेड म्यूटेक्स लॉक से सुरक्षित किया जाता है. (प्राथमिकता उलटने की वजह से, स्पिन लॉक का इस्तेमाल नहीं किया जा सकता)
    • पहचान फ़ाइल की गिनती के साथ नस्ल की स्थितियों को रोकने के लिए, म्यूचुअल एक्सक्लूज़न को शामिल करना ज़रूरी है.
    • लागू करना, ऑब्जेक्टिव-सी ऐटॉमिक प्रॉपर्टी से काफ़ी मिलता-जुलता है.

ऐटॉमिक के टाइप

Java में java.util.concurrent.atomic पैकेज में कई तरह के ऐटॉमिक मौजूद होते हैं. ये सभी, कस्टम इंप्लीमेंटेशन के साथ J2ObjC में पूरी तरह काम करते हैं.

फ़ाइनल फ़ील्ड

Java यह गारंटी देता है कि कोई थ्रेड, ऑब्जेक्ट के फ़ाइनल फ़ील्ड के लिए इनीशियलाइज़ की गई वैल्यू देखे. इसके लिए, ऑब्जेक्ट को शेयर करते समय किसी भी सिंक की ज़रूरत नहीं होनी चाहिए. (JSL-17.5) हालांकि, J2ObjC नॉन-वोलाटाइल ऑब्जेक्ट टाइप (ऊपर देखें) के ऐटॉमिक ऐक्सेस की सुविधा नहीं देता. इसलिए, बिना सिंक किए किसी ऑब्जेक्ट को शेयर करने का कोई सुरक्षित तरीका नहीं है. इसलिए, आखिरी फ़ील्ड के लिए ज़रूरी मेमोरी फ़ेंस को हटाकर, J2ObjC उपयोगकर्ता पर कोई और पाबंदी नहीं लगाई जाती.