توصیه شده, مقاله های سیسوگ

فرگمنتیشن چیست؟ + روش های جلوگیری از فرگمنتیشن حافظه

فرگمنتیشن

فرگمنتیشن یا چند تکه‌شدن حافظه حتی زمانی که حافظه آزاد زیادی در سیستم وجود داشته باشد، سبب پر شدن حافظه یا کمبود حافظه (out-of-memory) می‌شود. در هر سیستمی که فرگمنتیشن حافظه هر چند کم ولی به طور مداوم رخ دهد، out-of-memory رخ خواهد داد. این اتفاق به‌خصوص در سامانه‌های نهفته یا امبدد سیستم‌ها (embedded system) غیرقابل‌قبول است.

فرگمنتیشن چیست؟
فرگمنتیشن حافظه در زبان کامپیوتری به تقسیم‌بندی حافظه به قطعات کوچک‌تر با ویژگی‌های مشترک اطلاق می‌شود. این فرآیند می‌تواند در حافظه RAM، حافظه دیسک، و دیگر دستگاه‌های ذخیره‌سازی رخ دهد.

در برخی از محیط‌های نرم‌افزاری، مانند سیستم‌عامل‌ بلادرنگ OSE، ابزارهای خوبی برای جلوگیری از فرگمنتیشن حافظه وجود دارد؛ اما درنهایت انتخاب‌های برنامه‌نویس است که خروجی را تحت‌تأثیر قرار می‌دهد.

فرگمنتیشن حافظه چیست؟

حافظه فرگمنت شده در واقع حافظه آزاد غیرقابل‌ استفاده یک سیستم است. این بخش‌ها غیرقابل‌استفاده می‌مانند؛ زیرا مسئول تخصیص حافظه نمی‌تواند بخشی از حافظه را در دسترس برنامه قرار دهد. این مشکل معمولاً به این دلیل رخ می‌دهد که حافظه آزاد به بخش‌های کوچک تقسیم‌شده و به‌علاوه در مکان‌های مختلف پراکنده شده است.

ازآنجایی که روش تخصیص حافظه تعیین می‌کند که فرگمنتیشن حافظه به یک مشکل تبدیل شود یا خیر، تخصیص‌دهنده حافظه نقش مهمی در مدیریت منابع دارد.

زمان کامپایل و زمان اجرا

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

دلیل این است که کامپایلر طول عمر داده‌ها را درک می‌کند. اطلاع داشتن از طول عمر داده‌ها این امکان را فراهم می‌کند که داده‌ها به‌صورت پشته‌ای مرتب شوند. در واقع آخرین ورودی، اولین داده خروجی در ساختار خواهد بود. این ویژگی سبب می‌شود فردی که مسئول تخصیص حافظه است عملکرد کارآمدی داشته باشد و به‌علاوه فرگمنتیشن حافظه هم رخ ندهد.

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

تخصیص‌دهنده حافظه به 3 طریق سبب هدر رفتن حافظه می‌شود: سربار، فرگمنتیشن داخلی و فرگمنتیشن خارجی! تخصیص‌دهنده حافظه باید وضعیت تخصیص هر حافظه را در جایی ذخیره کند. این اطلاعات موقعیت، اندازه و مالکیت بلوک‌های آزاد و همچنین جزئیات دیگری که مربوط به وضعیت داخلی هستند را توصیف می‌کنند،‌ این قسمت در واقع همان سربار هستند، اما دو مبحث دیگر یعنی فرگمنتیشن داخلی و فرگمنتیشن خارجی چه هستند و چکونه باعث بروز مشکل می‌شوند ؟

انواع فرگمنتیشن

غالبا تخصیص‌دهنده در زمان اجرا حافظه بهتری به‌جز حافظه‌ای که مدیریت می‌کند برای ذخیره این اطلاعات ندارد. به همین دلیل تخصیص دهنده حافظه باید به یک سری اصول پایبند باشد. به طور مثال کل فرایند اختصاص دهی حافظه بسته به معماری پردازنده باید با آدرس‌های تقسیم‌پذیر بر 4، 8 یا 16 شروع شوند.

البته تخصیص‌دهنده حافظه ممکن است به دلایل دیگری، بلوک‌هایی با اندازه‌های خاص و تعریف‌شده به برنامه اختصاص دهد. هنگامی‌که برنامه برای یک بلوک 43 بایتی درخواست دهد می‌توان بلوک‌های 44 و 48 بایتی یا حتی بیشتر تحویل داد. فضای اضافی که به دلیل گرد کردن اندازه درخواستی به سمت بالا ایجاد می‌شود، فرگمنتیشن داخلی نامیده می‌شود.

فرگمنتیشن داخلی

فرگمنتیشن داخلی و خارجی

فرگمنتیشن داخلیفرگمنتیشن خارجی
اندازه بلوک حافظهزمانی اتفاق می افتد که بلوک حافظه، اندازه ثابتی داشته باشد.زمانی اتفاق می‌افتد که بلوک‌های حافظه تکه تکه شده، اندازه‌های متفاوتی داشته باشند.
زمان وقوعزمانی اتفاق می افتد که یک فرآیند به فضای بیشتری نیاز داشته باشد یا فضای کمتری نسبت به اندازه یک بلوک حافظه مصرف کند.زمانی اتفاق می افتد که یک فرآیند از حافظه اصلی حذف شود.
پردازشفرآیند فرگمنتیشن داخلی زمانی اتفاق می افتد که تقسیم بندی استفاده می شود.فرآیند فرگمنتیشن خارجی زمانی اتفاق می افتد که از سگمنتیشن استفاده می شود.
راه حلجستجوی بلوک مناسب بهترین راه حل برای فرگمنتیشن داخلی است.فشرده سازی راه حلی برای فرگمنتیشن خارجی است.

فرگمنتیشن خارجی وقتی رخ می‌دهد که بخش غیرقابل‌استفاده بین بلوک‌های تخصیص‌داده‌شده قرار بگیرد. به طور مثال این وضعیت وقتی رخ می‌دهد که سه بلوک پشت‌سرهم تخصیص‌داده‌شده باشد و سپس بلوک میانی از حالت تخصیص خارج شود. ممکن است تخصیص‌دهی حافظه از این بلوک مجدداً در فرایند تخصیص‌دهی بعدی استفاده کند؛ اما باید توجه داشته باشید که امکان تخصیص دهی بلوک به‌اندازه حافظه آزاد سیستم وجود ندارد.

فرگمنتیشن خارجی

برای درک بهتر مساله به عکس فوق نگاه کنید، با این که در مجموع سیستم ۵۰ کیلوبایت حافظه آزاد دارد، اما ما قادر نخواهیم بود یک بلوک ۵۰ کیلوبایتی از حافظه بگیریم،‌حتی قادر به گرفتن یک بلوک ۲۰ کیلو بایتی نیز نخواهیم بود، دقیقا به این دلیل که حافظه های آزاد در سیستم پشت سر هم قرار نگرفته اند، این پدیده را فرگمنتیشتن خارجی می‌نامیم.

درصورتی‌که تخصیص‌دهنده حافظه در زمان اجرا الگوریتم‌های خود را در پیاده‌سازی یا گرد کردن تغییر ندهد، حافظه سربار و فرگمنتیشن داخلی در طول عمر برنامه ثابت باقی می‌ماند. اگرچه حافظه سربار و فرگمنتیشن داخلی مطلوب نیستند و حافظه را هدر می‌دهد؛ اما فرگمنتیشن خارجی دشمن واقعی توسعه‌دهنده امبدد سیستم‌ها هستند به این دلیل که فرگمنتیشن خارجی نهایتا باعث از کار افتان سیستم‌ می‌شود.

 

چندین رویکرد جایگزین برای تعریف تکه تکه شدن حافظه وجود دارد که رایج‌ترین آن‌ها به شرح زیر است:

اولین روش فرگمنتیشناین تکنیک برای فرگمنتیشن خارجی استفاده می‌شود اما می‌توان با لحاظ‌کردن فرگمتیشن داخلی در مخرج فرمول فوق، برای فرگمنتیشن داخلی هم به کاربرد. فرگمنتیشن یک عدد اعشاری بین صفر و یک است. حافظه سیستمی که فرگمنتیشن آن یک (%100) باشد، کاملاً در وضعیت out of memory قرار دارد.

در سیستمی که همه حافظه یک بلوک آزاد است فرگمنتیشن صفر (%0) است. اگر یک‌چهارم کل حافظه بزرگ‌ترین بلوک آزاد باشد، فرگمنتیشن %75 است. به این مثال توجه کنید: سیستمی که 5 مگابایت حافظه آزاد دارد و بزرگترین بلوک آزاد آن ۵۰ کیلوبایت است یعنی فرگمنتیشن آن 99٪ است.

مثال فرگمنتیشن 99٪ یک نمونه واقعی است که در حین توسعه برنامه امبدد بلادرنگ رخ می‌دهد. این سطح از فرگمنتیشن یک ثانیه قبل از اینکه سیستم کرش کند، اتفاق می‌افتد. در یک آزمایش میدانی مشخص شد، اگر سیستمی به مدت دو هفته به‌صورت مداوم در حال اجرا باشد، به فرگمنتیشن ۹۹٪ می‌رسد؛ اما این مشکل چطور اتفاق می‌افتد و چرا این‌قدر دیر مشخص می‌شود؟

این سیستم قبلاً تست شده بود، اما تعدادی از تست‌ها بیش از دو ساعت طول کشیده بودند. فقط تست استرس نهایی یک آخر هفته به طول انجامید. مشکل به این دلیل رخ داد که اثرات فرگمنتیشن لزوماً در چنین دوره کوتاهی خود را نشان نمی‌دهند همین امر باعث می‌شود که مشکل فرگمنتیشن یکی از مشکلات مهم سیستم‌های امبدد باشد.

پاسخ به این سؤال که فرگمنتیشن طی چه مدتی به سطح بحرانی می‌رسد، دشوار است. در برخی موارد تحت شرایط خاص و قبل از اینکه حافظه پر شود، سیستم به یک وضعیت پایدار می‌رسد. در موارد دیگر ممکن است سیستم حتی با گذشت زمان به وضعیت پایدار نرسد. حذف عوامل عدم‌قطعیت و ریسک به همراه تخصیص حافظه بدون فرگمنتیشن در سیستم‌هایی که به‌سرعت به یک وضعیت پایدار می‌رسند، سبب می‌شوند که توسعه‌دهندگان آرامش خاطر بیشتری داشته باشند.

عامل مهم برای توسعه برنامه‌هایی که مدتی طولانی در حال اجرا هستند و شاید ماه‌ها یا سال‌ها ریست و یا ریبوت نمی‌شوند، این است که به‌سرعت به حالت پایدار برسند.

شاید برای شما مفید باشد: آموزش الکترونیک از مقدماتی تا پیشرفته

الگوریتم‌های رایج در تخصیص حافظه

الگوریتم های متفاوتی برای تخصیص حافظه وجود داره که هر کدوم معایب و مزایای خاص خودشون رو دارن و سخته که بخوایم بهترین الگورتیم تخصصیص حافظه رو انتخاب کنیم، در اوقع این انتخاب بر اساس نیاز و نحوه استفاده استکه مشخص میشود، در ادامه به بررسی چند الکوریتم مشهور می‌پردازیم.

 

 الگوریتم تخصیص حافظه  First Fit

first fit allocation

هنگام ریست ، PFREE برابر با NULL است و MBREAK به MSTART اشاره می‌کند. با ورود یک درخواست تخصیص حافظه، تخصیص‌دهنده ابتدا PFREE را بررسی می‌کند که بلوک‌های حافظه آزاد وجود دارد یا خیر. از آنجایی که PFREE برابر با NULL است، یک بلوک با اندازه درخواستی به‌اضافه یک هِدِر مدیریتی از MBREAK جدا می‌شود و MBREAK به‌روز می‌شود.

این فرایند تا زمانی که سیستم یک بلوک را آزاد کند، تکرار می‌شود. در این زمان هدر مدیریتی شامل اندازه بلوک است. در این هنگام، PFREE به‌گونه‌ای به‌روزرسانی می‌شود که از طریق لیست پیوندی به ابتدای بلوکی که آزاد شده است اشاره کند. خود بلوک هم با اشاره به یک محتوای قدیمی از PFREE به‌روزرسانی می‌شود تا یک لیست پیوندی ایجاد شود. دفعه بعدی که یک درخواست تخصیص ایجاد شود، سیستم در لیست پیوندی بلوک‌های آزاد جست‌وجو می‌کند تا اولین بلوکی که با اندازه مورد درخواست تطابق دارد را پیدا کند.

وقتی بلوک مناسبی پیدا شود، سیستم آن را به دو قسمت تقسیم می‌کند؛ یک قسمت را به برنامه بازمی‌گرداند و قسمت دیگر را به لیست حافظه‌های آزاد بازمی‌گرداند.

پیاده‌سازی الگوریتم First-fit ساده است و در ابتدا عملکرد خوبی دارد. بااین‌حال، زمانی که سیستم بلوک‌ها را به لیست حافظه‌های آزاد اضافه می‌کند، اتفاقی که می‌افتد این است که بلوک‌های بزرگ از ابتدای لیست حذف می‌شوند و بلوک‌های کوچک باقی‌مانده در ابتدای لیست قرار می‌گیرند.

در واقع الگوریتم First-fit به یک الگوریتم مرتب‌سازی تبدیل می‌شود که تمام فرگمنت‌های کوچک حافظه را در ابتدای لیست حافظه‌های آزاد قرار می‌دهد؛ بنابراین لیست حافظه‌های آزاد طولانی می‌شود به‌طوری‌که ممکن است بیش از صدها یا هزاران المان داشته باشد. به همین دلیل فرایند تخصیص حافظه طولانی و غیرقابل‌پیش‌بینی خواهد شد و تخصیص‌های بزرگ‌تر بیشتر از تخصیص‌های کوچک زمان‌بر خواهند بود؛ بنابراین محدودنکردن تقسیم بلوک‌های بزرگ به بلوک‌های کوچک سبب فرگمنتیشن زیاد خواهد شد. در زمان آزادسازی حافظه، حافظه به بلوک‌های کناری منتقل می‌شود البته اگر بلوک آزادی در مجاورت آن وجود داشته باشد.

اگرچه این رویکرد کمی کمک‌کننده است؛ اما الگوریتم first-fit برخلاف الگوریتم‌هایی که عملکرد هم‌زمانی و هم‌مکانی دارند، هیچ کاری در جهت افزایش احتمال آزادسازی بلوک‌های مجاور به طور همان زمان انجام نمی‌دهد.

الگوریتم Best-fit

best fit allocation

الگوریتم Best-fit مشابه الگوریتم first-fit است با این تفاوت که وقتی یک بلوک تخصیص داده می‌شود، سیستم لیست کل بلوک‌ها را بررسی می‌کند تا نزدیک‌ترین بلوک به اندازه درخواستی را پیدا کند. شیوه جست‌وجوی این الگوریتم بیشتر از الگوریتم first-fit طول می‌کشد؛ اما تفاوت زمانی موردنیاز برای تخصیص بلوک‌های کوچک و بزرگ حذف می‌شود.

الگوریتم Best-fit نسبت به الگوریتم first-fit، سبب فرگمنتیشن بیشتری می‌شود. دلیل این است که در این الگوریتم تمرکز بیشتری بر قراردادن فرگمنت‌های کوچک استفاده نشده در ابتدای لیست وجود دارد. به همین دلیل از این الگوریتم تقریباً هیچ‌وقت استفاده نمی‌شود.

الگوریتم Worst-fit

الگوریتم Worst-fit نیز به ندرت استفاده می‌شود. عملکرد این الگوریتم مشابه الگوریتم Best-fit است با این تفاوت که تمرکز بر این رویکرد سرعت بیشتری نسبت به best-fit دارد زیرا تمرکز بر تولید بلوک‌های بی‌استفاده کوچک کمتر است.

انتخاب مداوم بزرگ‌ترین بلوک آزاد برای تقسیم، احتمال اینکه قسمت باقیمانده برای مورد دیگری به‌اندازه کافی بزرگ باشد را افزایش می‌دهد.

 

تخصیص Buddy

تخصیص Buddy، برخلاف سایر تخصیص‌دهنده‌هایی که در این مقاله به توضیح آن‌ها پرداختیم، بر اساس نیاز از ابتدای حافظه مدیریت‌شده، بلوک‌های جدیدی ایجاد نمی‌کند. وجه اشتراک این روش با الگوریتم‌های دیگر این است که بلوک‌ها تقسیم و سپس با هم ادغام می‌شوند؛ اما این تقسیم‌بندی کاملاً به‌صورت رندوم انجام می‌شود.

هر بلوک یک دوست (friend یا buddy) دارد که می‌تواند به آن متصل شود و یا از آن جدا شود. تخصیص‌دهنده Buddy بلوک‌ها را در ساختار داده‌هایی که پیشرفته‌تر از لیست‌های پیوندی هستند، ذخیره می‌کند. اغلب ساختارها ترکیبی از باکت‌ها، درخت‌ها و هیپ‌ها هستند. توضیح دقیق اینکه تخصیص‌دهنده buddy چگونه عمل می‌کند دشوار است، چراکه تکنیک آن بسته به ساختار داده انتخاب شده تغییر می‌کند.

تخصیص‌دهنده buddy به دلیل دردسترس‌بودن ساختار داده‌های متغیر که ویژگی‌های شناخته‌شده‌ای دارند، مورداستفاده قرار می‌گیرد. سورس برخی از این ساختار داده‌ها نیز موجود است. نوشتن تخصیص‌دهنده‌های buddy غالباً پیچیده است. به‌علاوه ممکن است ویژگی‌های متغیری هم داشته باشند. معمولاً این تخصیص‌دهنده تا حدودی میزان فرگمنتیشن را محدود می‌کند.

جلوگیری از فرگمنتیشن حافظه

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

استفاده مجدد از بلوک‌ها

هدف این است که از بلوک‌ها بتوانیم بدون اینکه هر بار آن‌ها را به اندازه‌های دقیق تقسیم کنیم، بیشترین استفاده را داشته باشیم. تقسیم حافظه موجب ایجاد تعداد زیادی فرگمنت کوچک می‌شود که مانند ذرات شن هستند. مشکلی که به وجود می‌آید این است که بعداً نمی‌توان به‌راحتی این ذرات را کنار هم قرار داد. در عوض بهتر است برای هر بلوک چند بایت فضای بدون استفاده در نظر بگیریم.

تعداد بایت‌های اضافه به میزان نیاز برنامه شما برای جلوگیری از فرگمنتیشن، بستگی دارد. افزودن چند بایت فرگمنتیشن داخلی تخصیص‌های کوچک یک گام مثبت است. زمانی که یک برنامه درخواست 1 بایت حافظه می‌کند، مقداری که شما تخصیص خواهید داد، به عملکرد برنامه بستگی خواهد داشت.

اگر بخش قابل‌توجهی از تخصیص‌های برنامه 1 تا 16 بایت باشد، منطقی‌تر این است که 16 بایت برای تخصیص‌های کوچک در نظر بگیرید. همچنین می‌توان با محدود کردن بزرگ‌ترین بلوک قابل تخصیص، صرفه‌جویی قابل‌توجهی انجام داد. با این حال، این رویکرد منجر به این می‌شود که برنامه‌ها حین تخصیص بلوک‌هایی بزرگ‌تر از حد مجاز دچار مشکل شوند و از کار بیفتند.

کاهش اندازه‌ها یکی از راهکارهای کمک‌کننده در رفع این مشکل است. استفاده از اندازه‌هایی که به‌صورت لگاریتمی افزایش می‌یابند تا حدی زیادی میزان فرگمنتیشن را کاهش می‌دهد. به‌عنوان‌مثال، هر اندازه را می‌توان 20٪ بزرگ‌تر از اندازه قبلی در نظر گرفت. لحاظ کردن “یک اندازه برای همه” ممکن است روش درستی برای تخصیص حافظه در سیستم‌های نهفته نباشد. این روش به لحاظ فرگمنتیشن داخلی بسیار پرهزینه خواهد بود، با این حال سیستم تا حداکثر اندازه قابل پشتیبانی با فرگمنتیشن خارجی روبرو نخواهد شد.

اتصال بلوک‌ها

اتصال بلوک‌های آزاد مجاور به هم یک تکنیک واضح برای کاهش فرگمنتیشن حافظه است. برخی از الگوریتم‌های تخصیص حافظه مانند first-fit، به همین شیوه عمل می‌کنند؛ اما میزان موفقیت آن‌ها محدود است. اتصال بلوک‌های مجاور تنها می‌تواند در کاهش اثرات منفی الگوریتم تخصیص، کمک‌کننده باشد و نمی‌تواند مشکل اصلی را رفع کند. اگر اندازه بلوک‌ها محدود باشد، ممکن است اتصال بلوک‌های مجاور چندان آسان نباشد.

 

دسته‌بندی روش‌های تخصیص‌ حافظه

بعضی از تخصیص حافظه به‌اندازه‌ای پیشرفته هستند که در زمان اجرا آمارهایی از سبک تخصیص حافظه برنامه جمع‌آوری می‌کنند. سپس تمام تخصیص حافظه‌ها را بر اساس اندازه دسته‌بندی می‌کنند. به‌عنوان‌مثال، اندازه‌های کوچک، متوسط ​​و بزرگ. سیستم هر نوع تخصیص را به یک قسمت از حافظه مدیریت‌شده هدایت می‌کند که به اندازه‌های بلوک آن دسته مربوط می‌شود.

در این روش، اندازه‌های کوچک‌تر از اندازه‌های بزرگ‌تر تفکیک می‌شوند. این روش ترکیب جالبی از الگوریتم first-fit و یک مجموعه محدود از اندازه‌های ثابت است؛

هم‌جواری زمانی(Temporal Locality)

معمولاً استفاده کارآمد از هم‌جواری زمانی دشوار است؛ اما لازم ذکر است که تخصیص‌دهنده‌هایی که از تخصیص‌های هم‌جواری زمانی در حافظه استفاده می‌کنند، بیشتر با فرگمنتیشن حافظه روبرو خواهند شد. اگرچه تکنیک‌های دیگر ممکن است بتوانند این مشکل را کاهش دهند، باز هم محدودکردن تعداد بلوک‌هایی از حافظه که اندازه‌های مختلفی دارند، تکنیک کلیدی کاهش فرگمنتیشن خواهد بود.

محیط‌های نرم‌افزاری جدید ابزارهایی برای جلوگیری از فرگمنتیشن حافظه دارند. به‌عنوان‌مثال، سیستم‌عامل بلادرنگ OSE که به‌خصوص برای سیستم‌های مقاوم در برابر خطا، توزیع‌شده و با دسترسی بالا توسعه‌یافته است.

 

تخصیص‌دهنده حافظه Alloc

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

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

برای هر هشت اندازه، با استفاده از سه عبارت if می‌توان به این هدف دست‌یافت. سپس سیستم بلوک‌هایی را در قسمت هِد هر یک از هشت لیست آزاد درج و حذف می‌کند. در ابتدا، چرخه تخصیص حافظه استفاده نشده طول می‌کشد، اما همچنان سرعت آن بالا و در طول زمان ثابت است.

تخصیص‌دهنده heap malloc

تخصیص‌دهنده heap malloc

تخصیص‌دهنده heap malloc حافظه سربار کمتری (8 تا 16 بایت برای هر تخصیص) نسبت به alloc دارد و شما می‌توانید مالکیت خصوصی حافظه را غیرفعال کنید. تخصیص‌دهنده malloc بسیار سریع است. این تخصیص‌دهنده حافظه فرگمنتیشن داخلی کمتر و فرگمنتیشن خارجی بیشتری نسبت به alloc دارد.

heap malloc محدودیت حداکثر اندازه برای تخصیص دارد، بااین‌حال، در اکثر سیستم‌ها، این اندازه به مقدار کافی بزرگ است. مالکیت اشتراکی اختیاری و سربار کم سبب شده‌اند که malloc برای برنامه‌های C++ که آبجکت‌های کوچک و مشترک زیادی دارند، ایده‌آل باشد.

Heap در واقع به معنای پیاده‌سازی یک سیستم buddy به همراه یک ساختار داده داخلی است. در سیستم عامل OSE، سیستم ۲۸ اندازه متمایز دارد. هر اندازه جمع دو اندازه قبلی است و به این صورت یک دنباله فیبوناچی را تشکیل می‌دهند. اندازه‌ واقعی بلوک‌ها حاصل‌ضرب تعداد دنباله‌ها در 16 بایت هستند که شامل سربار تخصیص‌دهنده، یا هشت (یا 16 طبق اطلاعات فایل و لاین) بایت برای هر تخصیص می‌شود.

مدیرحافظه OSE بهترین عملکرد را وقتی دارد که به‌ندرت نیاز به بلوک‌های بزرگ حافظه داشته باشید. از برنامه‌های معمولی می‌توان برای تخصیص فضا برای کل برنامه‌ها، heap یا استخرها استفاده کرد. در برخی از پیاده‌سازی‌های سیستم‌های دارای MMU، از قابلیت MMU’s translation برای کاهش قابل‌توجه یا حتی حذف فرگمنتیشن استفاده کرد.

منبع

انتشار مطالب با ذکر نام و آدرس وب سایت سیسوگ، بلامانع است.

شما نیز میتوانید یکی از نویسندگان سیسوگ باشید.   همکاری با سیسوگ

1 دیدگاه در “فرگمنتیشن چیست؟ + روش های جلوگیری از فرگمنتیشن حافظه

  1. Avatar for A.T A.T گفت:

    سلام
    بسیار عالی منتظر قسمت های بعدی هستیم🙂

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *