هل قد تسألت ماهي ادارة ذاكرة الحاسب الخاصه بالبرامج والمترجم؟ لست أقصد كيف يدير نظام التشغيل Ram (paging & swapping ) فهذا موضوع اخر.
سلسلة تعنى بشرح كيف برنامجك/كودك يستخدم الذاكره ، وكيف المترجم "compiler" يصمم "layout" القسم الخاص بكل برنامج.
راح اتكلم عن Allocators عامةً
سلسلة تعنى بشرح كيف برنامجك/كودك يستخدم الذاكره ، وكيف المترجم "compiler" يصمم "layout" القسم الخاص بكل برنامج.
راح اتكلم عن Allocators عامةً
ملاحظة: سوف اتجاهل اغلب تفاصيل العتاد HW، حجم Page.
Alignement الخاصه بالمعمارية
Virtual addressing, Virtual Disk.
سوف اذكر malloc, free وكيف memory allocator تعمل، وخصوصا Stack Allocation
Heap Allocation
Global/Static Allocation.
كل برنامج لديه جزء من ذاكرة Ram من قبل النظام
Alignement الخاصه بالمعمارية
Virtual addressing, Virtual Disk.
سوف اذكر malloc, free وكيف memory allocator تعمل، وخصوصا Stack Allocation
Heap Allocation
Global/Static Allocation.
كل برنامج لديه جزء من ذاكرة Ram من قبل النظام
ذاكره لتخزين هذه البيانات والاوامر، ولكن حجم البيانات، وانواعها تختلف.
في قسم text seg هنا يتم وضع جميع الاوامر الخاصه بالبرنامج، مثال
5 + 4
لو افترضنا ان هذا الامر بعد التحويل الى Binary
0000011000110001 هذا الرقم سيتم تخزينه في مكان معين(عنوان) من ضمن Text seg
في قسم text seg هنا يتم وضع جميع الاوامر الخاصه بالبرنامج، مثال
5 + 4
لو افترضنا ان هذا الامر بعد التحويل الى Binary
0000011000110001 هذا الرقم سيتم تخزينه في مكان معين(عنوان) من ضمن Text seg
قسم Stack seg يتم تخزين بيانات ذات حجم ثابت Fixed/known size.
مثال :
boolean, int, char, etc...
هذه البيانات حجمها ثابت، int 32 bit , boolean 8 bit, char 8/16 bits وهكذا لذلك هذه البيانات يتم تخزينها بشكل ثابت(static) وغالبا المتغيرات داخل الدوال والباراميتر في الدوال.
مثال :
boolean, int, char, etc...
هذه البيانات حجمها ثابت، int 32 bit , boolean 8 bit, char 8/16 bits وهكذا لذلك هذه البيانات يتم تخزينها بشكل ثابت(static) وغالبا المتغيرات داخل الدوال والباراميتر في الدوال.
int main(int foo) {
char c = 'a';
}
المتغير "foo" و "c" احجامهم وقيمهم دائما معلومه وثابته لذلك يتم تخزينهم في Stack.
فيه معلومه جدا مهمه، لتخزين البيانات انت 1- تحتاج مساحة وتحتاج طريقة 2-لارجاع هذه المساحه للنظام حتى يتم استخدامها مره اخرى عند الحاجه.
char c = 'a';
}
المتغير "foo" و "c" احجامهم وقيمهم دائما معلومه وثابته لذلك يتم تخزينهم في Stack.
فيه معلومه جدا مهمه، لتخزين البيانات انت 1- تحتاج مساحة وتحتاج طريقة 2-لارجاع هذه المساحه للنظام حتى يتم استخدامها مره اخرى عند الحاجه.
في Stack seg تلقائياً عند تعريفك لمتغير مثل "c" او "foo" سوف يتم حجز مساحة لوضع القيم، وعند الخروج من نطاق الداله (scope) سوف يتم ارجاع هذه المساحه للنظام ويكون جاهز لاستقبال قيم جديده، لاحظ المعلومات الموجوده في الاعلى تحققت..تمكننا من حجز وارجاع المساحه ! رائع. لاحظ تلقائياً !!
انت لم تعمل شي لحجز المساحه او ارجاعها للنظام.
للاسف ليست كل البيانات معروفه compile-time, مثال: ماذا لو طلبت منك استقبال بيانات من المستخدم (user input) ؟ حينها لن نعرف حجم البيانات حتى نشغل البرنامج Run-time وبالتالي البيانات تكون unknown size حجم غير ثابت ! اين نخزنها؟ وكيف ؟
للاسف ليست كل البيانات معروفه compile-time, مثال: ماذا لو طلبت منك استقبال بيانات من المستخدم (user input) ؟ حينها لن نعرف حجم البيانات حتى نشغل البرنامج Run-time وبالتالي البيانات تكون unknown size حجم غير ثابت ! اين نخزنها؟ وكيف ؟
بمعنى Allocators
تعمل Linked list يتم تخزينهم في DataSeg وهذه LinkedList تعمل على توفير مساحة لهذه البيانات في وقت التنفيذ .
تعمل Linked list يتم تخزينهم في DataSeg وهذه LinkedList تعمل على توفير مساحة لهذه البيانات في وقت التنفيذ .
لذلك عند عمل مترجم ، تحتاج تعمل Allocation لGlobal data , Stack allocation .
وبعد ذلك تعمل Malloc باستخدام Global Data ومن ثم تسمية الجزء المستخدم من قبل malloc بـ heap
وبعد ذلك تعمل Malloc باستخدام Global Data ومن ثم تسمية الجزء المستخدم من قبل malloc بـ heap
لو افترضنا اني بعمل malloc
Block Head
Block *FreeList
SafePtr malloc(LargeEnough size) { … }
لاحظ Head و FreeList
سوف يتم تخزينهم في Global data اين يتم وضعهم؟ في Data segment الان لو اردت طلب 1KB هذه LinkedList سوف تحجز لي من DataSeg (لانها اساساً مخزنه في هذا الجزء) الحجم.
Block Head
Block *FreeList
SafePtr malloc(LargeEnough size) { … }
لاحظ Head و FreeList
سوف يتم تخزينهم في Global data اين يتم وضعهم؟ في Data segment الان لو اردت طلب 1KB هذه LinkedList سوف تحجز لي من DataSeg (لانها اساساً مخزنه في هذا الجزء) الحجم.
البعض يسأل لماذا احتاج malloc ، لماذا لا اخزن جميع classes + runtime data بنفسي في global data يعني هكذا مثلاً
MyClass *class = null
void init() {…}
بامكانك واحياناً يكون اسرع بس uninitialized بالاضافه الى انه لن تستفيد من الذاكره بافضل طريقة وهذا ماتوفره الـAllocators
MyClass *class = null
void init() {…}
بامكانك واحياناً يكون اسرع بس uninitialized بالاضافه الى انه لن تستفيد من الذاكره بافضل طريقة وهذا ماتوفره الـAllocators
يعملون طبقة من الـ Abstraction/Management بحيث :
تتبع الاماكن الفارغه في Data Seg وتتواصل مع نظام التشغيل لجلب مزيد من الذاكره وامور اخرى.
أخيراً، data seg له حجم معين وينتهي بعدها ثم نبدا نطلب من نظام التشغيل بجلب ذاكرة من Virtual memory (disk) وتعمل Swapping
تتبع الاماكن الفارغه في Data Seg وتتواصل مع نظام التشغيل لجلب مزيد من الذاكره وامور اخرى.
أخيراً، data seg له حجم معين وينتهي بعدها ثم نبدا نطلب من نظام التشغيل بجلب ذاكرة من Virtual memory (disk) وتعمل Swapping
هذا يجيب على سؤالي القديم هل malloc فقط تحجز عدد معين مثلاً 1GB او 2GB ؟
الاجابة لا طبعاً بامكانك حجز ذاكره حتى تمتلي RAM + Virtual Memory .
وهذا يعرف Virtual memory technique بحيث حجم البرنامج اكبر من حجم الذاكره.
انتهى، المعذره كنت مشغول الفترة الماضيه.
الاجابة لا طبعاً بامكانك حجز ذاكره حتى تمتلي RAM + Virtual Memory .
وهذا يعرف Virtual memory technique بحيث حجم البرنامج اكبر من حجم الذاكره.
انتهى، المعذره كنت مشغول الفترة الماضيه.
جاري تحميل الاقتراحات...