رم مجازی چیست و چگونه باعث افزایش سرعت گوشی ها در سیستم عامل اندروید می شود؟
رم مجازی را میتوان زیرساختی برای تمام سیستمعاملهای مولتی تسکینگ به حساب آورد که در این مطلب به صورت خاص مفهوم و کاربرد آن را در سیستمعامل اندروید مورد بررسی قرار خواهیم داد. هستهی مرکزی سیستمعامل اندروید در گوشی که اکنون با آن مشغول کار هستید، کرنل یا همان هستهی لینوکس قرار دارد که در واقع کار اصلی آن برقراری ارتباط بین سختافزار و کامپیوتر است. هستهی لینوکس وظیفهی مدیریت کردن منابع محاسباتی گوشی نظیر گرافیک، پردازنده، حافظهی داخلی، نمایشگر، شبکه و … را بر عهده دارد. مدیریت رم یا همان حافظهی دسترسی تصادفی (Random Access Memory) هم یکی از وظایف همین هسته به حساب میآید. اپلیکیشنها، سرویسهای در حال اجرا در پسزمینه و حتی خود سیستمعامل اندروید باید به رم دسترسی داشته باشند. حال لینوکس چگونه رم را پارتیشنبندی میکند و آن را در اختیار تمام موارد یادشده قرار میدهد موضوع بسیار مهمی است که باعث میشود گوشی روانتر کار کند. اینجا، یعنی روانتر شدن گوشی دقیقا جایی است که رم مجازی وارد عمل میشود.
حافظهی مجازی یا رم مجازی چیست؟
ابتدا یک توضیح مختصر در رابطه با اپلیکیشنها میدهیم که وقتی به حافظهی مجازی و تأثیر آن روی اپلیکیشنها میپردازیم، کمی مسأله برایتان روشنتر و قابل درکتر شود. هر اپلیکیشن از کدها و دادههای مختلفی بهره میبرد. این کدها وقتی که اپلیکیشنی را اجرا میکنید کاملا درون حافظهی رم قرار میگیرند. کد در یک زمان مشخص کار خود را شروع میکند و در هر لحظه یک دستورالعمل خاص را انجام میدهد. دادهها هم در همان لحظه از حافظهی داخلی خوانده شده، از شبکه بازپس گرفته و یا تولید میشوند. حتی میتواند ترکیبی از هر سهی اینها در جریان باشد. حال در هر منطقهای از حافظهی رم کدها یا دادهها با آدرس خاص خود شناخته میشوند. درست مثل آدرس پستی که به صورت منحصر بفردی مربوط به یک خانه است، کدها و دادهها هم آدرسهای خاص خود را در رم دارند.
حافظهی رم مجازی، دادههای اپلیکیشن را روی حافظهی رم اصلی سیستم شما نقشهبرداری میکند.
مشکل اصلی حافظهی رم سختافزاری اینجاست که اپلیکیشنها نمیدانند درست باید در کدام قسمت از حافظهی رم قرار بگیرند. بنابراین برای مثال اگر یک اپلیکیشن انتظار داشته باشد به آدرس ۱۲۰۴۸ برود، باید حتما به همان آدرس برود تا به بهترین شکل ممکن کار کند. اما این امکان وجود دارد که اپلیکیشن یادشده در جای دیگری قرار بگیرد و ۱۲۰۴۸ به عنوان منطقهی مورد انتظار آن، توسط اپلیکیشنی دیگر اشغال شود.
راه حلی که میتواند به حافظهی رم سختافزاری در تخصیص آدرس درست برای یک اپلیکیشن کمک کند، آدرس مجازی است که از ۰ تا ۴ گیگابایت یا حتی بیشتر را در بر میگیرد. حالا هر اپلیکیشنی میتواند آدرسی را که میخواهد داشته باشد. هر اپلیکیشن فضای آدرسی منحصر بفرد اما مجازی خود را دارد و دیگر نگران این نیست که یک اپلیکیشن دیگر ممکن است چه کاری انجام دهند. این آدرسهای مجازی روی یک منطقهی خاصی از حافظهی رم اصلی نقشهبرداری میشوند. این کار وظیفهی هستهی لینوکس هست که تمام نقشهبرداریها را انجام داده و آدرسهای مجازی را روی رم سختافزاری قرار میدهد.
چرا رم مجازی مفید است؟
رم مجازی با توجه به توضیحات داده شده بسیار مفید و برای افزایش سرعت گوشی تا حدودی ضروری است. در واقع باید آن را نمایشی دیجیتالی از حافظهی رم سختافزاری بدانیم که حضور دارد تا اپلیکیشنها بتوانند به آدرس خصوصی خود دسترسی داشته باشند چرا که میتوانند به گونهای مدیریت شوند که به صورت مستقل به اجرا در بیایند بدون اینکه آدرس اپلیکیشن دیگری را اشغال کنند و جلوی اجرای باسرعت آن را بگیرند.
این پایه و اساس تمام سیستمعاملهای مولتی تسکینگ را تشکیل میدهد که شامل اندروید هم میشود. اتفاقی که در اندروید میافتد این است که چون هر اپلیکیشن در فضای مختص به خود اجرا میشود، این سیستمعامل میتواند آن را اجرا کند، متوقف کند، به یک اپلیکیشن دیگر سوییچ کند، آن اپلیکیشن دیگر را اجرا کند و همینطور این فرایند ادامه پیدا میکند. بدون وجود حافظهی مجازی، مجبور خواهیم شد فقط یک اپلیکیشن را در هر لحظه در حالت اجرا در بیاوریم که باعث میشود سیستمعامل اندکی کند فعالیت کند.
این قابلیت حتی به اندروید این اجازه را میدهد تا فضاها را بین اپلیکیشنها تغییر دهد یا از zRAM استفاده کند تا بدین ترتیب شمار اپلیکیشنهایی که میتوانند در حافظه قرار داشته باشند قبل از اینکه برای اجرای یک اپلیکیشن دیگر، از حافظه پاک شوند. pageها در فضای مجازی و سختافزاری باید به یک اندازه باشند و عموما هم طول آنها به ۴K میرسد. برای اینکه بین صفحهها یا پیجهای مجازی و فیزیکی تفاوت قائل شویم، باید بگوییم مورد آخر یعنی فیزیکی، پیج فریم نامیده میشود و نه فقط پیج. در زیر میتوانید یک نمونهی ساده شده از نقشهبرداری ۶۴K حافظهی مجازی روی ۳۲K حافظهی سختافزاری را مشاهده کنید.
همانطور که میبینید، پیج ۰ از حافظهی رم مجازی (۰ تا ۴۰۹۵) روی پیج فریم ۲ در رم سختافزاری (۸۱۹۲ تا ۱۲۲۸۷) نقشهبرداری میشود. پیج ۱ در رم مجازی (۴۰۹۶ تا ۸۱۹۱) روی پیج فریم ۱ در رم سختافزاری (۴۰۹۶ تا ۸۱۹۱) و همینطور الی آخر. نکتهی جالبی که در این رابطه وجود دارد این است که تمام فضای مجازی قرار نیست روی فضای سختافزاری نقشهبرداری شود چرا که هر اپلیکیشن آنقدر آدرس در دسترس دارد که مشکلی آن را تهدید نمیکند و در نتیجه آنقدر فضا وجود دارد که نیازی به نقشهبرداری نیست. برخی از این فاصلههای خالی و پرنشده حتی شاید از لحاظ اندازه به چند گیگابایت هم برسند. مثلا اگر یک اپلیکیشن بخواهد به آدرس مجازی مثلا ۳۱۰۱ که در پیج ۰ از حافظهی رم قرار دارد دسترسی داشته باشد، باید وارد پیچ فریم ۳ از رم سختافزاری شود که به طور دقیق ۱۱۲۹۳ است.
واحد مدیریت حافظهی رم (MMU) به کمکتان میآید
پردازندههای جدید از فطعات سختافزاری اختصاصی بهره میبرند که وظیفهی نقشهبرداری بین رم مجازی و سختافزاری را بر عهده دارند. از این قطعهی سختافزاری با نام اختصار MMU یا همان واحد مدیریت رم یاد میشود که در واقع دربردارندهی نقشهای است که نشان میده هر پیج (آدرس رم مجازی) باید روی چه پیج فریمی (آدرس رم سختافزاری) قرار بگیرد. این یعنی سیستمعامل دیگر نیازی نیست این کار را انجام دهد چرا که به صورت خودکار توسط پردازنده که بسیار سریعتر و موثرتر است انجام میشود. خوبی پردازنده این است که میداند اپلیکیشنها تلاش میکنند به آدرسی در حافظهی رم مجازی دسترسی داشته باشند و سپس آن را روی رم فیزیمی معادلسازی میکنند. وظیفهی سیستمعامل هم فقط مدیریت فضاهایی است که توسط MMU یا همان واحد مدیریت حافظه استفاده میشوند.
MMU چگونه کار معالسازی را انجام میدهد؟
همانطور که مشاهده میکنید، سیستمعامل یک چارت پیج را بوجود میآورد و MMU هم با استفاده از آن، آدرسهای مجازی را به نمونههای سختافزاری معادلسازی میکند. برمیگردیم به مثالی که در بالا مطرح کردیم یعنی فضای ۳۱۰۱ که در واقع در باینری، همان ۱۱۰۱ ۰۰۰۱ ۱۱۰۰ ۰۰۰۰ ترجمه میشود. MMU این آدرس را به ۱۱۲۹۳ یا همان ۱۱۰۱ ۰۰۰۱ ۱۱۰۰ ۰۰۱۰ در حافظهی رم سختافزاری معادلسازی میکند. بنابراین به صورت کلی اینطور به نظر میرسد:
- اولین دستهی چهار بیتی یعنی ۰۰۰ همان شمارهی پیج مجازی هستند. این آدرس برای یافتن پیج فریم مربوطه در رم سختافزاری مورد استفاده قرار میگیرد.
- ورودی پیج ۰ در رم مجازی، پیج فریم ۲ در رم سختافزاری است که همان باینری ۰۰۱۰ است.
- بیت ۰۰۱۰ برای ساخت اولین بیت چهارتایی در رم سختافزاری مورد استفاده قرار میگیرد.
- ۱۲ بیت باقیمانده که بیت منشعب نامیده میشوند مستقیما در رم سختافزاری کپی میشوند.
تنها تفاون بین پیج ۳۱۰۱ و ۱۱۲۹۳ این است که بیت چهارتایی نخست آنها تغییر میکند تا پیجفایل مربوطه در رم سختافزاری را نشان دهد و نه رم مجازی. نقطه قوت استفاده از پیج این است که آدرس بعدی یعنی ۳۱۰۲ دقیقا از همین پیج فریم ۳۱۰۱ استفاده میکند. در واقع MMU از یک کش که Translation Lookaside Buffer (یک حافظهی میانی کوچک است که اطلاعات لازم را برای تبدیل آدرسهای مجازی به فیزیکی در خود دارد و به اختصار TBL هم نامیده میشود) استفاده میکند تا سرعت معادلسازی افزایش پیدا کند.
حافظهی میانی یا TBL چیست؟
TLB که در بالا به توضیح سادهی آن پرداختیم به حافظهی کش معادلسازیهای اخیر میگویند که توسط MMU اجرا میشود. قبل از اینکه یک آدرس معادلسازی شود، MMU چک میکند ببیند آیا کش تبدیل پیج به پیج فریم در TLB قرار گرفته است یا خیر. اگر کش پیج درخواست شده در دسترس باشد، معادلسازی آن هم بلافاصله صورت میگیرد.
هر ورودی TLB برای خود معمولا فقط از پیج یا پیج فریم بره میبرد بلکه مواردی نظیر نوع حافظهی رم، شرایط کش، مجوزهای دسترسی و … را نیز شامل میشود. اگر TLB از ورودی معتبری برای حافظهی رم مجازی بهره نبرد که این یک خطا در نظر گرفته میشود، MMU مجبور میشود پیج فریم را از جدول مربوطه پیدا کند. از آنجایی هم که این جدول خودش بخشی از حافظهی رم است، در واقع MMU نیاز پیدا میکند تا بار دیگر به حافظهی رم دسترسی پیدا کند. سختافزار تعبیه شده درون MMU این جازه را به آن میدهد تا جدول معادلسازی را به سرعت در حافظهی رم بخواند. زمانی که معادلسازی جدیدی صورت میگیرد، کش آن میتواند برای استفادههای احتمالی در آینده در رم ذخیره شود.
آیا همه چیز به همین سادگی است؟
از یک طرف، به نظر میرسد معادلسازی توسط MMU بسیار ساده و بدون هیچگونه پیچیدگی صورت بگیرد. یک جستوجوی ساده و کپی کردن دادهها از طریق بیتها. اما یک سری مشکل وجود دارد که باعث میشود همه چیز خیلی پیچیدهتر از چیزی باشد که فکرش را میکنید.
مثالهایی که در بالا مطرح شد در واقع برای یک حافظهی ۶۴K بود. اما در دنیای واقعی، با رمهایی با صدها مگابایت یا گیگابایت سر و کار داریم. یک جدول ۳۲ بیتی کامل حدودا ۴ مگابایت است. هر اپلیکیشن هم به جدول صفحه (جدول پیج یا همان پیج تیبل که با توجه به ویکیپدیا، یک ساختار داده است که مورد استفادهی یک سیستم حافظهی مجازی در یک سیستمعامل به منظور ذخیره کردن آدرسهای مجازی حافظه، منطبق بر آدرسهای فیزیکی حافظه قرار میگیرد) مختص خود نیاز دارد. برای مثال اگر ۱۰۰ فعالیت در حال اجرا داشته باشید، شامل اپلیکیشنها، سرویسهای پسزمینه، سرویسهای اندروید و …، این یعنی ۴۰۰ مگابایت از حافظهی رم نیاز است تا فقط جدول صفحه را کنترل کند.
داستان زمانی پیچیدهتر میشود که بدانید اگر از ۳۲ بیت فراتر بروید، جدولهای صفحهها باید برای همیشه در رم باقی بمانند و امکان جابهجایی یا فشردهسازی آنها وجود ندارد. مهمتر اینکه جدول صفحه به یک ورودی برای هر پیج نیاز دارد حتی در صورتی که اصلا مورد استفاده قرار نمیگیرد و پیج فریم مخصوص خود را ندارد.
راه حل این است که از یک جدول صفحه چند سطحه استفاده شود. در مثال بالا دیدیم که چهار بیت به عنوان شمارهی پیج مورد استفاده قرار گرفت. این امکان وجود دارد که جدول به چندین بخش مختلف تقسیم شود. دو بیت اول مرجعی برای جدول دیگر هستند. آن قهرست خودش جدول صفحه تمام آدرسهایی را که شامل آن دو بیت میشوند هم در برمیگیرد. بنابراین یک جدول صفحه برای تمام آدرسهایی که به ۰۰ آغاز میشود، در اختیار داریم، یکی برای ۰۱ و دیگری هم برای ۱۰ و در نهایت هم ۱۱ که میشود چهار جدول صفحه به علاوهی یک جدول سطح بالا.
جدول سطح بالا باید در حافظهی رم باقی بماند اما چهار جدول دیگر میتوانند در صورت نیاز جابهجا شوند. اگر هم آدرسی وجود نداشته باشد که از ۱۱ شروع شود، بنابراین هیچ جدول صفحهای هم نیاز نخواهد بود. در دنیای واقعی، این جدولها در واقع میتوانند چهار یا پنج سطح عمیق داشته باشند. هر جدول هم جدول دیگری را مرتبط با بیتس مرتبط در هر آدرس نشان میدهد.
در بالا میتوانید جدولی را مشاهده میکنید که در آن مهندسان، ۴۸ بیت آدرس مجازی را معادلسازی کردهاند. هر ورودی جدول صفحه پرچمهایی در فضاهایی دارد که توسط آن اعداد انشعابی مورد استفاده قرار میگیرد. بیت مجوز R ،W و X نشان میدهد که آیا پیج قابل خواندن، نوشتن و اجرا هست یا خیر. وقتی مقادیر مربوط به هر سهی اینها صفر باشد، ورودی جدول صفحه در واقع نمایانگر رسیدن به سطح بعدی خواهد بود. در غیر این صورت، یک ورودی معیوب خواهد بود و باید عملیات مربوط به جستوجو صورت برای رفع ایراد آن آغاز شود.
اندروید چگونه پیجهای مشکلدار را مدیریت میکند؟
وقتی MMU و سیستمعامل هماهنگی بینقصی با یکدیگر داشته باشند، همه چیز خوب پیش میرود. اما یک سری مشکلاتی هم وجود دارد. برای مثال وقتی MMU سعی در جستوجوی یک آدرس مجازی داشته باشد و نتواند آن را در جدول صفحه پیدا کند چه اتفاقی میافتد؟ این مشکل به عنوان نقص صفحه یا Page Fault در نظر گرفته میشود و انواع مختلفی هم دارد.
- نقص صفحهی سخت: پیج فریم در حافظهی رم قرار ندارد و باید از zRAM بارگذاری شود.
- نقص صفحهی نرم: هنگامی که صفحه در لحظهی وقوع خطا در حافظهی رم بارگذاری شود اما در MMU به عنوان یک صفحهی بارگذاری شده تشخیص داده نشود. سیستم مدیریت صفحههای معیوب یا ناقص در سیستمعامل در این مرحله دست بکار شده و باید برای آن صفحه در MMU یک ورودی تولید کند. این اتفاق زمانی رخ میدهد که یک حافظه توسط اپلیکیشنهای مختلف مورد استفاده قرار میگیرد، یا از قبل وارد حافظهی رم شده است و یا زمانی که یک اپلیکیشن درخواست فضایی از رم را ارسال میکند اما این فضا به درستی به آن اختصاص داده نمیشود و در نتیجه این اپلیکیشن باید منتظر دسترسی به صفحهی نخست باشد.
- نقص صفحهی نامعتبر: اپلیکیشن در تلاش است تا به حافظهی رمی دسترسی پیدا کند که اصلا در فضای آدرس آن قرار ندارد. این باعث میشود دسترسی نامعتبری صورت بگیرد. این اتفاق زمانی رخ میدهد که یک برنامه سعی میکند در یک حافظهی فقط قابل خواندن نوشته شود یا اینکه بافر پر شود.
فوائد حافظهی رم مجازی
همانطور که مشاهده کردید، حافظهی رم مجازی راهی است که شرکتهای تولیدکنندهی گوشیهای هوشمند برای کمک به رم فیزیکی و اصلی گوشی از آن استفاده میکنند تا بدین ترتیب اپلیکیشنها بتوانند به صورت مستقل از حافظهی رم استفاده کنند بدون اینکه نگران این باشند که ممکن است اپلیکیشن دیگری از فضای مربوط به آنها در رم استفاده کند. این کار به اندروید و گوشیهای مبتنی بر این سیستمعامل کمک میکند تا مولتی تسکینگ را با سرعت نسبتا بیشتری نسبت به حالت عادی مدیریت کنند و انجام دهند.
بدون حافظهی رم مجازی، گوشیهای هوشمند ما محدود به اجرای هر اپلیکیشن در یک زمان میشوند. اپلیکیشنها نمیتوانند جابهجا شوند یا به صورت کلی هر اقدامی در راستای نگهداری بیش از یک اپلیکیشن در حافظهی رم باعث میشود مشکل بوجود بیاید. دفعهی دیگری که یک اپلیکیشن را اجرا میکنید، متوجه میشوید که دقیقا چه اتفاقی درون پردازنده در حال رخ دادن است و اندروید دارد چه کاری انجام میدهد تا تجربهای روان و لذتبخش از کار با گوشی داشته باشید.