نموذج ذاكرة J2ObjC

يصف هذا المستند طريقة إدارة الذاكرة ضمن الرمز المُترجَم لـ J2ObjC، وكيف تعمل البرامج عند الوصول إلى الذاكرة المشتركة.

إدارة الذاكرة

يتمثّل أحد أهداف شركة J2ObjC في إنتاج رمز مترجمة سيتم دمجه بسلاسة في بيئة عدّ المراجع لـ FALSE-C. وهذا يجعل تعليمة Java المترجَمة سهلة الاستخدام من Goal-C المكتوب محليًا لأنه لا يوجد نقل غير مريح لملكية الكائنات التي يتم تمريرها بين بيئات Java وTarget-C.

نظرًا لأن Java تستخدم جمع البيانات المُهملة لإدارة الذاكرة، لا تحتوي لغة Java على إدارة صريحة للذاكرة لكائناتها. لهذا السبب، على شركة J2ObjC إدراج استدعاءات حساب المراجع بشكل مناسب لضمان نقل العناصر في الوقت المناسب. لقد استقرنا على مجموعة القواعد التالية التي وجدنا أنها فعالة وعملية في آن واحد:

  • ستظل جميع العناصر نشطة لمدة على الأقل مدة مجموعة الإطلاق التلقائي الحالية.
    • تتيح لنا هذه القاعدة العامة تخطي العديد من عمليات الاحتفاظ بالبيانات والإصدارات التي كانت ضرورية بخلاف ذلك.
  • لا يتم الاحتفاظ بالمتغيرات المحلية.
    • لا يتم احتساب استدعاءات احتساب المتغيرات على قراءات أو كتابة المتغيرات المحلية.
  • سيتم الاحتفاظ بالحقول.
    • يحتفظ تخصيص استدعاءات حقل بالقيمة الجديدة ويتم الإصدار التلقائي للقيمة القديمة.
  • ويتم إطلاق الكائنات الجديدة تلقائيًا على الفور. (ما لم يتم تعيينه إلى حقل على الفور)

الدورات المرجعية

توجد الدورة المرجعية عندما يشير كائن إلى نفسه إما بشكل مباشر أو غير مباشر من خلال حقوله. يمكن تنظيف الدورات المرجعية من خلال مجموعة البيانات المهملة في Java، ولكن قد يحدث تسرّب للذاكرة في بيئة عد المراجع في Object-C. ما من طريقة آلية لمنع حدوث الدورات المرجعية، إلا أننا نوفّر أداة 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 الضمانات نفسها المتوفّرة في Java لجميع حقول volatile. يستخدم J2ObjC الآليات التالية لحقول volatile:

  • يتم ربط الأنواع الأساسية بالأنواع الذرية لـ c11.
    • مثال: volatile int -> _Atomic(jint)
  • حقول العناصر محمية باستخدام عمليات قفل دالة الاستبعاد المتبادل pthread. (لا يمكن استخدام أقفال الدوران بسبب قلب الأولوية)
    • ويُعتبر الاستبعاد المتبادل شرطًا لمنع حالات العِرق من خلال احتساب المراجع.
    • يشبه التنفيذ إلى حد كبير الخصائص الذرية لـ Object-C.

الأنواع الذرية

توفر لغة Java عددًا من الأنواع البسيطة في حزمة java.util.concurrent.atomic. يتوفّر كلّ ذلك بالكامل في J2ObjC من خلال عمليات تنفيذ مخصَّصة.

الحقول النهائية

تضمن Java أن سلسلة التعليمات ترى القيم المهيأة للحقول النهائية للكائن بدون الحاجة إلى أي مزامنة عند مشاركة الكائن. (JSL-17.5) ومع ذلك، بما أن J2ObjC لا يتيح الوصول الذري لأنواع الكائنات غير المتطايرة (انظر أعلاه)، فلا توجد طريقة آمنة لمشاركة كائن بدون مزامنة. لذلك، لا يتم وضع أي قيود إضافية على مستخدم J2ObjC عن طريق حذف سياجات الذاكرة اللازمة للحقول النهائية.