مدل حافظه J2ObjC

این سند نحوه مدیریت حافظه تحت کد ترجمه شده J2ObjC و نحوه عملکرد برنامه ها هنگام دسترسی به حافظه مشترک را توضیح می دهد.

مدیریت حافظه

یکی از اهداف J2ObjC تولید کد ترجمه شده است که به طور یکپارچه در محیط شمارش مرجع Objective-C ادغام می شود. این کار کد جاوای ترجمه شده را برای استفاده از Objective-C که به صورت بومی نوشته شده است آسان می کند، زیرا هیچ انتقال نامناسبی از مالکیت برای اشیایی که بین محیط های جاوا و Objective-C ارسال می شوند وجود ندارد.

از آنجایی که جاوا از جمع‌آوری زباله برای مدیریت حافظه استفاده می‌کند، کد جاوا شامل هیچ مدیریت حافظه صریحی از اشیاء خود نیست. بنابراین J2ObjC باید فراخوانی شمارش مرجع را به طور مناسب وارد کند تا اطمینان حاصل شود که اشیاء در زمان مناسب توزیع می شوند. ما بر روی مجموعه قوانین زیر که به نظرمان عملی و کاربردی هستند، اکتفا کرده ایم:

  • همه اشیاء حداقل برای مدت زمان ذخیره خودکار آزاد فعلی زنده خواهند بود.
    • این قانون کلی به ما این امکان را می‌دهد که از بسیاری از حفظ‌ها و رهاسازی‌هایی که در غیر این صورت ضروری بودند بگذریم.
  • متغیرهای محلی حفظ نمی شوند.
    • هیچ مرجع شمارش برای خواندن یا نوشتن متغیرهای محلی فراخوانی نمی کند.
  • فیلدها حفظ می شوند.
    • تخصیص یک فیلد فراخوانی مقدار جدید را حفظ می کند و آزادسازی خودکار روی مقدار قدیمی.
  • اشیاء جدید بلافاصله آزاد می شوند. (مگر اینکه فوراً به یک زمینه اختصاص داده شود)

چرخه های مرجع

یک چرخه مرجع زمانی وجود دارد که یک شی به طور مستقیم یا غیرمستقیم از طریق فیلدهای خود به خود ارجاع دهد. چرخه های مرجع را می توان با جمع آوری زباله جاوا پاک کرد، اما حافظه را در محیط شمارش مرجع Objective-C نشت می کند. هیچ راه خودکاری برای جلوگیری از وقوع چرخه های مرجع وجود ندارد. با این حال، ما ابزار Cycle Finder را ارائه می دهیم که تشخیص چرخه ها را خودکار می کند. در اینجا چند راه متداول برای رفع یک چرخه مرجع آورده شده است:

  • برای تضعیف یکی از مراجع، حاشیه نویسی @Weak یا @WeakOuter اضافه کنید.
  • یک متد cleanup() را به یکی از اشیا اضافه کنید که برخی از فیلدها را null می کند. قبل از دور انداختن شیء cleanup() فراخوانی کنید.
  • برای جلوگیری از ایجاد چرخه مرجع، کد را دوباره طراحی کنید.

حافظه مشترک

در یک برنامه چند رشته ای، برخی از داده ها را می توان توسط چندین رشته به اشتراک گذاشت. جاوا ابزارهای مختلفی را برای دسترسی ایمن به داده های مشترک فراهم می کند. این بخش پشتیبانی J2ObjC برای دسترسی به داده های مشترک را توضیح می دهد.

همگام شده است

J2ObjC کلمه کلیدی synchronized را مستقیماً به Objective-C @synchronized نگاشت می کند.

اتمی

جاوا اتمی بودن را برای بارها و همه نوع ذخیره می کند به جز long و double . JLS-17.7 را ببینید. به استثنای میدان های volatile (توضیح داده شده در زیر)، J2ObjC هیچ درمان خاصی برای اطمینان از بارهای اتمی و ذخیره سازی ارائه نمی دهد. این دلالت بر موارد زیر دارد:

  • از آنجایی که همه پلتفرم‌های iOS 32 یا 64 بیتی هستند، بارها و ذخیره‌های انواع اولیه به جز long و double در دستگاه‌های 32 بیتی اتمی هستند و همه در سیستم‌های 64 بیتی اتمی هستند.
  • بارها و ذخایر انواع شی در J2ObjC اتمی نیستند.
    • به روز رسانی اتمی تعداد مراجع بسیار پرهزینه است.
    • یک میدان شی را می توان با اعلام volatile اتمی ساخت. (پایین را ببینید)

زمینه های فرار

برای فیلدهای volatile ، جاوا هم اتمی و هم ترتیب پی در پی سازگار را فراهم می کند ( JLS-8.3.1.4 )، که می تواند برای همگام سازی استفاده شود. J2ObjC تضمین های مشابه جاوا را برای همه فیلدهای volatile ارائه می دهد. J2ObjC از مکانیسم های زیر برای میدان های volatile استفاده می کند:

  • انواع اولیه به انواع اتمی c11 نگاشت می شوند.
    • به عنوان مثال. volatile int -> _Atomic(jint)
  • فیلدهای شی با قفل های mutex pthread محافظت می شوند. (به دلیل وارونگی اولویت نمی توان از قفل چرخشی استفاده کرد)
    • حذف متقابل برای جلوگیری از شرایط مسابقه با شمارش مرجع ضروری است.
    • پیاده سازی بسیار شبیه به ویژگی های اتمی Objective-C است.

انواع اتمی

جاوا تعدادی نوع اتمی را در بسته java.util.concurrent.atomic ارائه می کند. همه اینها به طور کامل در J2ObjC با پیاده سازی های سفارشی پشتیبانی می شوند.

فیلدهای نهایی

جاوا تضمین می کند که یک thread مقادیر اولیه فیلدهای نهایی یک شی را بدون نیاز به هیچ گونه هماهنگی در هنگام اشتراک گذاری شی می بیند. ( JSL-17.5 ) با این حال، از آنجایی که J2ObjC از دسترسی اتمی انواع شی غیر فرار پشتیبانی نمی کند (به بالا مراجعه کنید)، هیچ راه امنی برای اشتراک گذاری یک شی بدون همگام سازی وجود ندارد. بنابراین، با حذف حصارهای حافظه لازم برای فیلدهای نهایی، هیچ محدودیت اضافی بر روی کاربر J2ObjC اعمال نمی شود.