memory-management - ماذا وأين هي كومة وكومة؟


وتشرح كتب لغة البرمجة أن أنواع القيم يتم إنشاؤها على المكدس، وأنواع المراجع يتم إنشاؤها على كومة الذاكرة المؤقتة، دون توضيح ما هي هذه الأمور. أنا لم أقرأ شرحا واضحا لهذا. أنا أفهم ما هي كومة ، ولكن أين وما هي (فيزيائيا في ذاكرة الكمبيوتر الحقيقي)؟

  • إلى أي مدى يتم التحكم فيها من قبل نظام التشغيل أو وقت تشغيل اللغة؟
  • ما هو نطاقها؟
  • ما الذي يحدد حجم كل منها؟
  • ما الذي يجعل واحد أسرع؟


Answers


المكدس هو مجموعة الذاكرة جانبا كما مساحة الصفر لمؤشر التنفيذ. عندما يتم استدعاء وظيفة، يتم حجز كتلة على الجزء العلوي من المكدس للمتغيرات المحلية وبعض البيانات مسك الدفاتر. وعندما تعود هذه الدالة، تصبح الكتلة غير مستخدمة ويمكن استخدامها في المرة التالية التي تسمى فيها الدالة. يتم الاحتفاظ المكدس دائما في ليفو (آخر في أول من)؛ آخر كتلة محفوظة مؤخرا هو دائما كتلة المقبل ليتم تحريرها. وهذا يجعل من السهل حقا لتتبع المكدس. تحرير كتلة من المكدس ليس أكثر من تعديل مؤشر واحد.

كومة الذاكرة المؤقتة هي الذاكرة تعيين جانبا لتخصيص ديناميكية. على عكس كومة، لا يوجد نمط فرض لتوزيع و ديالوكاتيون من كتل من كومة الذاكرة المؤقتة. يمكنك تخصيص كتلة في أي وقت وتحريره في أي وقت. هذا يجعل الأمر أكثر تعقيدا لتتبع أي أجزاء من كومة الذاكرة المؤقتة يتم تخصيص أو مجانا في أي وقت من الأوقات. هناك العديد من مخصصات كومة مخصصة المتاحة لضبط أداء كومة لأنماط الاستخدام المختلفة.

كل خيط يحصل على كومة، في حين أن هناك عادة كومة واحدة فقط للتطبيق (على الرغم من أنه ليس من غير المألوف أن يكون أكوام متعددة لأنواع مختلفة من التخصيص).

للإجابة على أسئلتك مباشرة:

إلى أي مدى يتم التحكم فيها من قبل نظام التشغيل أو وقت تشغيل اللغة؟

يخصص نظام التشغيل المكدس لكل مؤشر ترابط على مستوى النظام عند إنشاء مؤشر الترابط. عادة ما يسمى نظام التشغيل عن طريق وقت تشغيل اللغة لتخصيص كومة للتطبيق.

ما هو نطاقها؟

يتم إرفاق كومة إلى مؤشر الترابط، لذلك عندما يتم إنهاء مؤشر الترابط كومة. يتم تخصيص كومة الذاكرة المؤقتة عادة عند بدء تشغيل التطبيق بواسطة وقت التشغيل، ويتم استصلاحها عند تطبيق (عملية من الناحية الفنية) مخارج.

ما الذي يحدد حجم كل منها؟

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

ما الذي يجعل واحد أسرع؟

كومة أسرع لأن نمط الوصول يجعل من تافهة لتخصيص وإزالة الذاكرة من ذلك (مؤشر / عدد صحيح هو ببساطة زيادة أو تناقص)، في حين أن كومة لديها مسك الدفاتر أكثر تعقيدا تشارك في تخصيص أو ديالوكاتيون. أيضا، كل بايت في المكدس يميل إلى إعادة استخدامها في كثير من الأحيان مما يعني أنه يميل إلى تعيينها إلى ذاكرة التخزين المؤقت للمعالج، مما يجعلها سريعة جدا. آخر أداء ضرب ل كومة الذاكرة المؤقتة هو أن كومة، في الغالب مورد عالمي، وعادة ما يجب أن تكون متعددة خيوط آمنة، أي كل تخصيص و ديالوكاتيون يحتاج إلى أن تكون - عادة - متزامنة مع "جميع" كومة أخرى الوصول في البرنامج.

مظاهرة واضحة:
مصدر الصورة: vikashazrati.wordpress.com




كومة:

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

كومة:

  • تخزينها في ذاكرة الوصول العشوائي الكمبيوتر تماما مثل المكدس.
  • في C ++، يجب تدمير المتغيرات على كومة الذاكرة المؤقتة يدويا وأبدا تسقط من النطاق. يتم تحرير البيانات مع delete ، delete[] ، أو free .
  • أبطأ لتخصيص بالمقارنة مع المتغيرات على المكدس.
  • تستخدم عند الطلب لتخصيص كتلة من البيانات لاستخدامها من قبل البرنامج.
  • يمكن أن يكون تجزئة عندما يكون هناك الكثير من التخصيصات و ديالوكاتيونس.
  • في C ++ أو C، سيتم الإشارة إلى البيانات التي تم إنشاؤها على كومة من قبل المؤشرات وتخصيصها مع new أو malloc على التوالي.
  • يمكن أن يكون هناك فشل في تخصيص إذا كان هناك حاجة إلى حجم كبير جدا من المخزن المؤقت.
  • يمكنك استخدام كومة الذاكرة المؤقتة إذا كنت لا تعرف بالضبط كم البيانات التي سوف تحتاج في وقت التشغيل أو إذا كنت بحاجة إلى تخصيص الكثير من البيانات.
  • مسؤولة عن تسرب الذاكرة.

مثال:

int foo()
{
  char *pBuffer; //<--nothing allocated yet (excluding the pointer itself, which is allocated here on the stack).
  bool b = true; // Allocated on the stack.
  if(b)
  {
    //Create 500 bytes on the stack
    char buffer[500];

    //Create 500 bytes on the heap
    pBuffer = new char[500];

   }//<-- buffer is deallocated here, pBuffer is not
}//<--- oops there's a memory leak, I should have called delete[] pBuffer;



النقطة الأكثر أهمية هي أن كومة الذاكرة المؤقتة والمكدس هي مصطلحات عامة للطرق التي يمكن تخصيص الذاكرة. ويمكن تنفيذها بطرق مختلفة، وتنطبق المصطلحات على المفاهيم الأساسية.

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

    بساطة كومة هو أنك لا تحتاج إلى الحفاظ على جدول يحتوي على سجل لكل قسم من الذاكرة المخصصة. معلومات الدولة الوحيدة التي تحتاج إليها هي مؤشر واحد إلى نهاية المكدس. لتخصيص وإلغاء تخصيص، كنت مجرد زيادة و إنقاص هذا المؤشر واحد. ملاحظة: يمكن أن يتم تنفيذ كومة في بعض الأحيان لبدء في الجزء العلوي من قسم من الذاكرة وتمتد إلى أسفل بدلا من النمو صعودا.

  • في كومة، لا يوجد ترتيب معين لطريقة توضع العناصر. يمكنك الوصول إلى وإزالة العناصر في أي أمر لأنه لا يوجد بند "أعلى" واضح.

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

وينبغي لهذه الصور القيام بعمل جيد إلى حد ما لوصف طريقتين لتخصيص وتحرير الذاكرة في كومة وكومة. يم!

  • إلى أي مدى يتم التحكم فيها من قبل نظام التشغيل أو وقت تشغيل اللغة؟

    كما ذكر، كومة وكومة هي المصطلحات العامة، ويمكن تنفيذها في نواح كثيرة. عادة ما تحتوي برامج الكمبيوتر على كومة تسمى مكدس المكالمة الذي يقوم بتخزين المعلومات ذات الصلة بالوظيفة الحالية مثل المؤشر لأي وظيفة تم استدعاؤها منها، وأي متغيرات محلية. لأن وظائف استدعاء وظائف أخرى ومن ثم العودة، كومة ينمو ويتقلص لعقد المعلومات من وظائف أبعد من المكدس المكالمة. برنامج ليس لديها حقا التحكم في وقت التشغيل أكثر من ذلك؛ انها تحددها لغة البرمجة، نظام التشغيل وحتى بنية النظام.

    كومة الذاكرة المؤقتة هي مصطلح عام يستخدم لأي ذاكرة يتم تخصيصها بشكل حيوي وبشكل عشوائي. أي خارج النظام. عادة ما يتم تخصيص الذاكرة من قبل نظام التشغيل، مع تطبيق وظائف أبي الدعوة للقيام بهذا التخصيص. هناك قليلا من النفقات العامة المطلوبة في إدارة الذاكرة المخصصة ديناميكيا، والتي عادة ما يتم التعامل معها من قبل نظام التشغيل.

  • ما هو نطاقها؟

    كومة المكالمة هي مثل هذا المفهوم مستوى منخفض أنه لا تتعلق "النطاق" بمعنى البرمجة. إذا قمت بتفكيك بعض التعليمات البرمجية سترى مراجع نمط المؤشر النسبي إلى أجزاء من المكدس، ولكن بقدر ما يتعلق لغة مستوى أعلى، تفرض اللغة قواعدها الخاصة. ومع ذلك، فإن أحد الجوانب الهامة للمكدس هو أنه بمجرد عودة الدالة، يتم تحرير أي شيء محلي لهذه الوظيفة على الفور من المكدس. هذا يعمل بالطريقة التي تتوقع أن يعمل بها نظرا لكيفية عمل لغات البرمجة الخاصة بك. في كومة، فإنه من الصعب أيضا تحديد. النطاق هو ما يتعرض له نظام التشغيل، ولكن لغة البرمجة الخاصة بك ربما يضيف قواعده حول ما هو "نطاق" في التطبيق الخاص بك. تستخدم بنية المعالج ونظام التشغيل العنوان الظاهري، الذي يترجمه المعالج إلى عناوين فعلية وهناك أخطاء في الصفحات، وما إلى ذلك. تتبع الصفحات التي تنتمي إليها التطبيقات. أنت لا تحتاج أبدا للقلق حول هذا، على الرغم من ذلك، لأنك مجرد استخدام أي طريقة تستخدم لغة البرمجة الخاصة بك لتخصيص وذاكرة مجانية، والتحقق من وجود أخطاء (إذا فشل التخصيص / التجميع لأي سبب).

  • ما الذي يحدد حجم كل منها؟

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

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

  • ما الذي يجعل واحد أسرع؟

    كومة أسرع لأن جميع الذاكرة الحرة هي دائما متجاورة. لا تحتاج إلى الحفاظ على قائمة من جميع شرائح الذاكرة الحرة، مجرد مؤشر واحد إلى أعلى الحالي من المكدس. عادة ما يقوم المجمعون بتخزين هذا المؤشر في سجل خاص وسريع لهذا الغرض. ما هو أكثر من ذلك، تتركز العمليات اللاحقة على كومة عادة في المناطق القريبة جدا من الذاكرة، والتي على مستوى منخفض جدا هو جيد للتحسين من قبل مخابئ المعالج على يموت.




(لقد نقلت هذه الإجابة من سؤال آخر كان أكثر أو أقل خداع من هذا واحد).

الجواب على سؤالك هو تنفيذ محددة وقد تختلف عبر المجمعين وبنية المعالج. ومع ذلك، هنا هو شرح مبسط.

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

كومة الذاكرة المؤقتة

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

المدخنة

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

هل يمكن تخصيص وظيفة على كومة الذاكرة المؤقتة بدلا من كومة؟

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

كيف تتم إدارة كومة الذاكرة المؤقتة حقا إلى بيئة التشغيل. C يستخدم malloc و C ++ يستخدم new ، ولكن العديد من اللغات الأخرى لديها جمع القمامة.

ومع ذلك، فإن كومة هي ميزة أكثر مستوى منخفض ترتبط ارتباطا وثيقا بنية المعالج. زيادة كومة الذاكرة المؤقتة عندما لا يكون هناك مساحة كافية ليست صعبة جدا لأنه يمكن تنفيذها في المكالمة مكتبة أن يعالج كومة الذاكرة المؤقتة. ومع ذلك، فإن نمو كومة غالبا ما يكون مستحيلا كما يتم اكتشاف تجاوز كومة فقط عندما يكون فوات الأوان. وإغلاق موضوع التنفيذ هو الخيار الوحيد القابل للتطبيق.




في التعليمات البرمجية C # التالية

public void Method1()
{
    int i = 4;
    int y = 2;
    class1 cls1 = new class1();
}

وإليك كيفية إدارة الذاكرة

Local Variables التي تحتاج فقط إلى آخر طالما الدالة استدعاء تذهب في كومة. يتم استخدام كومة الذاكرة المؤقتة للمتغيرات التي لم نكن نعرف حقا مدى الحياة ولكن نتوقع منهم أن تستمر لفترة من الوقت. في معظم اللغات أنه من الأهمية بمكان أن نعرف في وقت تجميع كم كبير المتغير إذا كنا نريد لتخزينها على المكدس.

الكائنات (التي تختلف في حجم كما نقوم بتحديثها) تذهب في كومة لأننا لا نعرف في وقت الإنشاء متى أنها سوف تستمر. في العديد من اللغات الكومة هي القمامة التي تم جمعها للعثور على الأشياء (مثل الكائن cls1) التي لم يعد لديك أي مراجع.

في جافا، معظم الكائنات تذهب مباشرة إلى كومة الذاكرة المؤقتة. في لغات مثل C / C ++، ستروكتس والطبقات يمكن أن تبقى في كثير من الأحيان على كومة عندما كنت لا تتعامل مع مؤشرات.

ويمكن الاطلاع على مزيد من المعلومات هنا:

الفرق بين كومة وتخصيص الذاكرة كومة «timmurphy.org

و هنا:

إنشاء كائنات على كومة وكومة

هذه المقالة هي مصدر الصورة أعلاه: ستة مفاهيم هامة .NET: كومة، كومة، أنواع القيمة، أنواع المرجع، الملاكمة، و أونبوكسينغ - كوديبروجيكت

ولكن كن على علم قد تحتوي على بعض عدم الدقة.




المكدس عند استدعاء الدالة يتم وضع الوسيطات لهذه الوظيفة بالإضافة إلى بعض النفقات العامة الأخرى على المكدس. كما يتم تخزين بعض المعلومات (مثل أين تذهب على العودة) هناك. عند تعريف متغير داخل الدالة، يتم تخصيص هذا المتغير أيضا على المكدس.

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

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

وهكذا، فإن كومة الذاكرة المؤقتة هي أكثر تعقيدا بكثير، لأن هناك في نهاية المطاف يجري مناطق الذاكرة التي هي غير المستخدمة معشق مع قطع التي هي - الذاكرة يحصل مجزأة. العثور على ذاكرة مجانية من الحجم الذي تحتاجه مشكلة صعبة. وهذا هو السبب في تجنب كومة الذاكرة المؤقتة (على الرغم من أنه لا يزال يستخدم في كثير من الأحيان).

تنفيذ تنفيذ كل من كومة وكومة الذاكرة المؤقتة عادة ما يكون إلى وقت التشغيل / نظام التشغيل. في كثير من الأحيان الألعاب وغيرها من التطبيقات التي هي الأداء الحاسم خلق حلول الذاكرة الخاصة بهم التي انتزاع قطعة كبيرة من الذاكرة من كومة ثم طبق عليه داخليا لتجنب الاعتماد على نظام التشغيل للذاكرة.

هذا هو عملي فقط إذا كان استخدام الذاكرة الخاصة بك يختلف تماما عن القاعدة - أي للألعاب حيث يمكنك تحميل مستوى في عملية واحدة ضخمة، ويمكن تشاك في الكثير كله بعيدا في عملية ضخمة أخرى.

الموقع الفعلي في الذاكرة هذا هو أقل ملاءمة مما تظن بسبب تقنية تسمى الذاكرة الظاهرية مما يجعل برنامجك يعتقد أن لديك حق الوصول إلى عنوان معين حيث البيانات المادية في مكان آخر (حتى على القرص الصلب!). العناوين التي تحصل على المكدس هي في تزايد النظام كما شجرة المكالمة يحصل أعمق. عناوين كومة الذاكرة المؤقتة هي غير قابلة للتنبؤ (أي إمبليمنتاتيون محددة) وبصراحة ليست مهمة.




لتوضيح، هذه الإجابة لديها معلومات غير صحيحة ( توماس إصلاح إجابته بعد التعليقات، بارد :)). إجابات أخرى فقط تجنب شرح ما يعني تخصيص ثابت. لذلك سوف أشرح الأشكال الرئيسية الثلاثة للتخصيص وكيفية ارتباطها عادة بجزء كومة الذاكرة المؤقتة والمكدس والبيانات أدناه. وأود أيضا أن تظهر بعض الأمثلة في كل من C / C ++ وبيثون لمساعدة الناس على فهم.

لا يتم تخصيص المتغيرات "الثابتة" (أكا المخصصة بشكل أساسي) على المكدس. لا تفترض ذلك - كثير من الناس يفعلون فقط لأن "ثابت" يبدو الكثير مثل "كومة". أنها موجودة في الواقع في لا كومة ولا كومة. وهي جزء من ما يسمى قطاع البيانات .

ومع ذلك، فمن الأفضل عموما النظر في " النطاق " و " مدى الحياة " بدلا من "كومة" و "كومة".

نطاق يشير إلى ما أجزاء من التعليمات البرمجية يمكن الوصول إلى متغير. عموما نحن نفكر في النطاق المحلي (يمكن فقط الوصول إليها من قبل وظيفة الحالية) مقابل النطاق العالمي (يمكن الوصول إليها في أي مكان) على الرغم من أن نطاق يمكن الحصول على أكثر تعقيدا بكثير.

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

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

سوف أقدم بعض التعليمات البرمجية C المشروح بسيط لتوضيح كل هذا. أفضل طريقة للتعلم هي تشغيل برنامج تحت مصحح الأخطاء ومشاهدة السلوك. إذا كنت تفضل قراءة الثعبان، تخطي إلى نهاية الجواب :)

// Statically allocated in the data segment when the program/DLL is first loaded
// Deallocated when the program/DLL exits
// scope - can be accessed from anywhere in the code
int someGlobalVariable;

// Statically allocated in the data segment when the program is first loaded
// Deallocated when the program/DLL exits
// scope - can be accessed from anywhere in this particular code file
static int someStaticVariable;

// "someArgument" is allocated on the stack each time MyFunction is called
// "someArgument" is deallocated when MyFunction returns
// scope - can be accessed only within MyFunction()
void MyFunction(int someArgument) {

    // Statically allocated in the data segment when the program is first loaded
    // Deallocated when the program/DLL exits
    // scope - can be accessed only within MyFunction()
    static int someLocalStaticVariable;

    // Allocated on the stack each time MyFunction is called
    // Deallocated when MyFunction returns
    // scope - can be accessed only within MyFunction()
    int someLocalVariable;

    // A *pointer* is allocated on the stack each time MyFunction is called
    // This pointer is deallocated when MyFunction returns
    // scope - the pointer can be accessed only within MyFunction()
    int* someDynamicVariable;

    // This line causes space for an integer to be allocated in the heap
    // when this line is executed. Note this is not at the beginning of
    // the call to MyFunction(), like the automatic variables
    // scope - only code within MyFunction() can access this space
    // *through this particular variable*.
    // However, if you pass the address somewhere else, that code
    // can access it too
    someDynamicVariable = new int;


    // This line deallocates the space for the integer in the heap.
    // If we did not write it, the memory would be "leaked".
    // Note a fundamental difference between the stack and heap
    // the heap must be managed. The stack is managed for us.
    delete someDynamicVariable;

    // In other cases, instead of deallocating this heap space you
    // might store the address somewhere more permanent to use later.
    // Some languages even take care of deallocation for you... but
    // always it needs to be taken care of at runtime by some mechanism.

    // When the function returns, someArgument, someLocalVariable
    // and the pointer someDynamicVariable are deallocated.
    // The space pointed to by someDynamicVariable was already
    // deallocated prior to returning.
    return;
}

// Note that someGlobalVariable, someStaticVariable and
// someLocalStaticVariable continue to exist, and are not
// deallocated until the program exits.

وهناك مثال مؤثرة بشكل خاص من السبب في أنه من المهم التمييز بين مدى الحياة، ونطاق هو أن متغير يمكن أن يكون نطاق محلي ولكن عمر ثابت - على سبيل المثال، "someLocalStaticVariable" في نموذج التعليمات البرمجية أعلاه. ويمكن لهذه المتغيرات تجعل عادات تسمية شائعة ولكنها غير رسمية لدينا مربكة جدا. على سبيل المثال عندما نقول " المحلية " نحن عادة يعني " متغير محليا خاصة بتطبيق المخصصة تلقائيا " وعندما نقول عالمية نقصد عادة " على مستوى العالم راقب المخصصة بشكل ثابت متغير ". لسوء الحظ عندما يتعلق الأمر أشياء مثل " ملف راقب المتغيرات المخصصة بشكل ثابت " كثير من الناس فقط ويقول ... " هاه ؟؟؟ ".

بعض الخيارات بناء الجملة في C / C ++ تفاقم هذه المشكلة - على سبيل المثال الكثير من الناس يعتقدون المتغيرات العالمية ليست "ثابتة" بسبب بناء الجملة هو مبين أدناه.

int var1; // Has global scope and static allocation
static int var2; // Has file scope and static allocation

int main() {return 0;}

لاحظ أن وضع الكلمة "ثابت" في الإعلان أعلاه يمنع var2 من وجود نطاق عالمي. ومع ذلك، فإن VAR1 العالمية لديها مخصصات ثابتة. هذه ليست بديهية! لهذا السبب، وأنا أحاول أن تستخدم أبدا كلمة "ثابت" عند وصف نطاق، وبدلا من قول شيء مثل "ملف" أو "ملف محدودة" النطاق. ولكن الكثير من الناس استخدام عبارة "ثابت" أو "نطاق ثابت" لوصف متغير التي يمكن الوصول إليها فقط من ملف التعليمات البرمجية واحد. في سياق مدى الحياة، "ثابت" دائما يعني يتم توزيع متغير في بداية البرنامج ويتم deallocated عند إنهاء البرنامج.

بعض الناس يعتقدون أن هذه المفاهيم كما C / C ++ محددة. هم ليسوا. على سبيل المثال، العينة بيثون أدناه يوضح كل الأنواع الثلاثة من توزيع (هناك بعض الاختلافات الطفيفة المحتملة في اللغات تفسر أنني لن ندخل هنا).

from datetime import datetime

class Animal:
    _FavoriteFood = 'Undefined' # _FavoriteFood is statically allocated

    def PetAnimal(self):
        curTime = datetime.time(datetime.now()) # curTime is automatically allocatedion
        print("Thank you for petting me. But it's " + str(curTime) + ", you should feed me. My favorite food is " + self._FavoriteFood)

class Cat(Animal):
    _FavoriteFood = 'tuna' # Note since we override, Cat class has its own statically allocated _FavoriteFood variable, different from Animal's

class Dog(Animal):
    _FavoriteFood = 'steak' # Likewise, the Dog class gets its own static variable. Important to note - this one static variable is shared among all instances of Dog, hence it is not dynamic!


if __name__ == "__main__":
    whiskers = Cat() # Dynamically allocated
    fido = Dog() # Dynamically allocated
    rinTinTin = Dog() # Dynamically allocated

    whiskers.PetAnimal()
    fido.PetAnimal()
    rinTinTin.PetAnimal()

    Dog._FavoriteFood = 'milkbones'
    whiskers.PetAnimal()
    fido.PetAnimal()
    rinTinTin.PetAnimal()

# Output is:
# Thank you for petting me. But it's 13:05:02.255000, you should feed me. My favorite food is tuna
# Thank you for petting me. But it's 13:05:02.255000, you should feed me. My favorite food is steak
# Thank you for petting me. But it's 13:05:02.255000, you should feed me. My favorite food is steak
# Thank you for petting me. But it's 13:05:02.255000, you should feed me. My favorite food is tuna
# Thank you for petting me. But it's 13:05:02.255000, you should feed me. My favorite food is milkbones
# Thank you for petting me. But it's 13:05:02.256000, you should feed me. My favorite food is milkbones



وقد أجاب آخرون السكتات الدماغية واسعة بشكل جيد جدا، ولذا فإنني سوف رمي في بعض التفاصيل.

  1. كومة كومة وليس بالضرورة أن تكون صيغة المفرد. والحالة الشائعة التي لديك كومة واحد أو أكثر إذا كان لديك أكثر من موضوع واحد في العملية. في هذه الحالة كل موضوع له كومة الخاص بها. يمكنك أيضا أن يكون كومة أكثر من واحد، على سبيل المثال بعض تكوينات DLL يمكن أن يؤدي إلى دلس مختلفة تخصيص من أكوام مختلفة، وهذا هو السبب انها عموما فكرة سيئة لتحرير الذاكرة المخصصة من قبل مكتبة مختلفة.

  2. في C يمكنك الحصول على فائدة من تخصيص طول متغير من خلال استخدام alloca ، الذي يخصص على المكدس، في مقابل الوك، الذي يخصص على الكومة. وهذه الذاكرة لا البقاء على قيد الحياة البيان عودتك، ولكن من المفيد لمنطقة عازلة الصفر.

  3. جعل مخزن مؤقت كبير على ويندوز التي لا تستخدمها معظم ليست حرة. وذلك لأن المترجم سوف تولد حلقة كومة التحقيق الذي يسمى كل مرة يتم إدخال وظيفة للتأكد من وجود كومة (لأن Windows يستخدم صفحة حارس واحد في نهاية الكدسة للكشف عندما يحتاج أن ينمو المكدس. إذا كنت الوصول إلى الذاكرة أكثر من صفحة واحدة على نهاية كومة سوف تحطم). مثال:

void myfunction()
{
   char big[10000000];
   // Do something that only uses for first 1K of big 99% of the time.
}



البعض الآخر قد أجاب على سؤالك مباشرة، ولكن عند محاولة فهم المكدس وكومة، وأعتقد أنه من المفيد النظر في تخطيط الذاكرة لعملية UNIX التقليدية (بدون المواضيع و mmap()موزعي المستندة). في الذاكرة إدارة مسرد صفحة ويب لديها مخطط من هذا التخطيط الذاكرة.

كومة كومة وتقع تقليديا على طرفي نقيض من مساحة العنوان الظاهرية للعملية. كومة ينمو تلقائيا عند الوصول إليها، وتصل إلى حجم مجموعة من نواة (والتي يمكن تعديلها مع setrlimit(RLIMIT_STACK, ...)). ينمو كومة عند استدعاء مخصص ذاكرة brk()أو sbrk()استدعاء النظام، ورسم خرائط المزيد من الصفحات من الذاكرة الفعلية في مساحة العنوان الظاهري للعملية.

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




اعتقد كثير من الناس الآخرين قد أعطاك الإجابات الصحيحة في أغلبها حول هذه المسألة.

واحد التفاصيل التي تم تفويتها، ومع ذلك، هو أن "كومة" ينبغي في الواقع ربما أن يطلق عليه "متجر الحرة". والسبب في هذا التمييز هو أن المخزن المجاني الأصلي تم تنفيذها مع بنية البيانات المعروفة باسم "كومة ذات الحدين." لهذا السبب، وتخصيص من تطبيقات في وقت مبكر من malloc () / مجانا () كان تخصيص من الكومة. ومع ذلك، في هذا العصر الحديث، يتم تنفيذ معظم المتاجر الحرة مع هياكل البيانات المعقدة جدا التي ليست أكوام ذات الحدين.




المكدس جزء من الذاكرة التي يمكن التلاعب بها عبر عدة تعليمات لغة التجميع الرئيسية، مثل 'البوب' (إزالة وإرجاع قيمة من المكدس) و'دفع' (دفع قيمة إلى كومة)، ولكن أيضا استدعاء ( استدعاء روتين - وهذا يدفع عنوان للعودة إلى كومة) والعودة (عودة من روتين - وهذا دفعها عنوان الخروج من المكدس ويقفز إلى ذلك). انها منطقة الذاكرة أدناه سجل مؤشر مكدس، التي يمكن وضعها حسب الحاجة. يستخدم كومة أيضا لتمرير الوسائط إلى الوظائف الفرعية، وأيضا للحفاظ على القيم في السجلات قبل استدعاء الوظائف الفرعية.

كومة هي جزء من الذاكرة التي تعطى للتطبيق من قبل نظام التشغيل، وعادة من خلال syscall مثل malloc. على أنظمة تشغيل الحديثة هذه الذاكرة هي مجموعة من الصفحات التي فقط عملية الاستدعاء لديه حق الوصول إلى.

يتم تحديد حجم المكدس في وقت التشغيل، وعموما لا تنمو بعد إطلاق البرنامج. في برنامج C، المكدس يحتاج إلى أن تكون كبيرة بما يكفي لاحتواء كل متغير أعلن في كل وظيفة. سوف كومة تنمو بشكل ديناميكي حسب الحاجة، ولكن OS أنها تقوم في نهاية المطاف المكالمة (فإنه غالبا ما تنمو في كومة من قبل أكثر من القيمة التي malloc المطلوبة، بحيث على الأقل بعض mallocs المستقبل لا حاجة للذهاب إلى نواة ل الحصول على مزيد من الذاكرة. يعتبر هذا السلوك في كثير من الأحيان للتخصيص)

لأنك المخصصة المكدس قبل إطلاق البرنامج، تحتاج أبدا إلى malloc قبل أن تتمكن من استخدام المكدس، ولهذا أفضلية طفيفة هناك. في الممارسة العملية، فإنه من الصعب جدا التنبؤ بما سوف تكون سريعة وماذا سيكون بطيئا في أنظمة التشغيل الحديثة التي لديها أنظمة فرعية الذاكرة الظاهرية، لأنه كيف يتم تنفيذ الصفحات وحيث يتم تخزينها هو تفصيل تطبيق.




ما هو كومة؟

مكدس هو كومة من الأشياء، وعادة واحد هو أن رتبت بعناية.

الأكوام في أبنية الحوسبة هي مناطق الذاكرة حيث يتم إضافة البيانات أو إزالتها بطريقة مشاركة في الحادية والمغادرة.
في تطبيق متعددة الخيوط، وسيكون لكل موضوع يكون كومة الخاصة به.

ما هو كومة؟

كومة هي مجموعة غير مرتب من الأشياء تراكمت بشكل عشوائي.

في الحوسبة أبنية كومة هي مساحة الذاكرة المخصصة بشكل حيوي التي يتم إدارتها تلقائيا بواسطة نظام التشغيل أو مكتبة إدارة الذاكرة.
يتم تخصيص الذاكرة على كومة، يتم deallocated، وحجمها بانتظام أثناء تنفيذ البرنامج، وهذا يمكن أن يؤدي إلى تجزئة مشكلة اسمها.
يحدث تجزئة عندما يتم تخصيص الكائنات الذاكرة مع المساحات الصغيرة بين التي هي صغيرة جدا للاحتفاظ الأشياء ذاكرة إضافية.
والنتيجة الصافية هي النسبة المئوية من مساحة كومة غير قابلة للاستخدام الذاكرة مزيد من المخصصات.

الاثنين معا

في تطبيق متعددة الخيوط، وسيكون لكل موضوع يكون كومة الخاصة به. ولكن، فإن جميع المواضيع المختلفة تشترك في الكومة.
لأن المواضيع المختلفة تشترك في كومة في تطبيق متعددة الخيوط، وهذا يعني أيضا أن يجب أن يكون هناك بعض التنسيق بين المواضيع بحيث أنها لا تحاول الوصول إلى والتلاعب نفس قطعة (ق) من الذاكرة في كومة في نفس الوقت.

وهو أسرع - كومة أو كومة؟ و لماذا؟

المكدس أسرع بكثير من الكومة.
وذلك لأن الطريقة التي يتم تخصيص تلك الذاكرة على المكدس.
تخصيص الذاكرة على كومة بسيطة مثل تحريك كومة المؤشر لأعلى.

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

جافا الذاكرة نموذج

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




يمكنك أن تفعل بعض الأشياء مثيرة للاهتمام مع مكدس. على سبيل المثال، لديك وظائف مثل alloca (على افتراض يمكنك الحصول على الماضي التحذيرات وفيرة بشأن استخدامه)، الذي هو شكل من أشكال malloc يستخدم خصيصا المكدس، وليس كومة، للذاكرة.

أن، أخطاء الذاكرة القائمة على كومة قال بعض من أسوأ اشهده. إذا كنت تستخدم ذاكرة كومة، والتي تجاوز حدود كتلة المخصصة، لديك فرصة لائق من التسبب خطأ القطاع. (وليس 100٪: قد تكون كتلة بك متجاورة بالمناسبة مع آخر أن كنت قد خصصت سابقا). ولكن منذ المتغيرات التي تم إنشاؤها على كومة دائما متجاورة مع بعضها البعض، والكتابة خارج الحدود يمكن تغيير قيمة متغير آخر. تعلمت أنه كلما أشعر أن برنامجي توقف طاعة قوانين المنطق، فإنه ربما تجاوز سعة المخزن المؤقت.




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

كومة هي مساحة الذاكرة تخصيص الذاكرة الديناميكية مصنوعة من (وضوحا "الجديد" أو "تخصيص" المكالمات). وهو هيكل البيانات الخاصة التي يمكن أن تتبع كتل الذاكرة بمساحات مختلفة وحالة توزيعها.

في أنظمة "الكلاسيكية" وضعت RAM من هذا القبيل أن مؤشر مكدس بدأ بها في الجزء السفلي من الذاكرة، بدأ مؤشر كومة من في القمة، وأنها نمت تجاه بعضهم البعض. إذا كانت تتداخل، كنت خارجا من ذاكرة الوصول العشوائي. أن لا يعمل مع أنظمة تشغيل متعددة الخيوط الحديثة بالرغم من ذلك. كل موضوع لا بد أن يكون كومة الخاصة به، وهذه يمكن الحصول على خلق بشكل دينامي.




من WikiAnwser.

كومة

عندما وظيفة أو وسيلة تدعو وظيفة أخرى وهذا بدوره يدعو وظيفة أخرى، وما إلى ذلك، وتنفيذ جميع هذه المهام يبقى معلقا حتى ترجع الدالة مشاركة جدا قيمته.

هذه سلسلة من المكالمات وظيفة مع وقف التنفيذ هي كومة، لأن عناصر في المكدس (المكالمات وظيفة) تعتمد على بعضها البعض.

المكدس المهم النظر في عمليات الإعدام معالجة الاستثناء والموضوع.

كومة

كومة هو ببساطة الذاكرة المستخدمة من قبل برامج لتخزين المتغيرات. عنصر من كومة (المتغيرات) ليس لديهم تبعيات مع بعضها البعض ويمكن دائما الوصول عشوائيا في أي وقت.




كومة

  • وصول سريع جدا
  • ليس لديك لصراحة إلغاء تخصيص المتغيرات
  • ويدير الفضاء كفاءة من خلال وحدة المعالجة المركزية، وذاكرة لا تصبح مجزأة
  • المتغيرات المحلية فقط
  • الحد الأقصى لحجم كومة (التي تعتمد على OS)
  • المتغيرات لا يمكن تغيير حجم

كومة

  • يمكن الوصول إلى المتغيرات على الصعيد العالمي
  • لا يوجد حد لحجم الذاكرة
  • (نسبيا) أبطأ الوصول
  • لا كفاءة استخدام مضمونة من الفضاء، قد تصبح الذاكرة مجزأة مع مرور الوقت كما يتم تخصيص كتل الذاكرة، ثم أطلق سراحهم
  • يجب أن إدارة الذاكرة (كنت مسؤولا عن تخصيص وتحرير المتغيرات)
  • يمكن تغيير حجم المتغيرات باستخدام realloc ()



في 1980s، نشر UNIX مثل الأرانب مع الشركات الكبرى المتداول خاصة بهم. كان إكسون واحد كما فعل عشرات من الأسماء التجارية خسر أمام التاريخ. كيف وضعت ذاكرة من كان في تقدير العديد من المنفذين.

تم وضع برنامج C نموذجية خارج الشقة في الذاكرة مع فرصة لزيادة عن طريق تغيير قيمة BRK (). عادة، كان هيب فقط أقل من هذه القيمة BRK وزادت زيادة BRK كمية من كومة المتاحة.

كان كومة واحدة عادة مساحة أقل هيب الذي كان الجهاز الذاكرة التي تحتوي على شيء من القيمة حتى الجزء العلوي من كتلة ثابتة القادم من الذاكرة. وكان هذا كتلة المقبل في كثير من الأحيان CODE التي يمكن الكتابة بواسطة البيانات المكدس في واحدة من الخارقة الشهيرة في عصره.

كان كتلة واحدة الذاكرة نموذجي BSS (كتلة من القيم صفر) الذي تم عن طريق الخطأ لا ركزت في طرح الشركة المصنعة واحد. وكان آخر البيانات التي تحتوي على قيم تهيئة، بما في ذلك سلاسل والأرقام. كان ثلث CODE تحتوي على CRT (C وقت التشغيل)، الرئيسية، وظائف، والمكتبات.

ظهور الذاكرة الظاهرية في UNIX يغير الكثير من القيود. ليس هناك سبب موضوعي لماذا تحتاج هذه الكتل تكون متجاورة، أو ثابتة في الحجم، أو أمرت بطريقة معينة الآن. وبطبيعة الحال، قبل UNIX كان مالتيكس التي لا تعاني من هذه القيود. هنا هو تخطيطي يظهر أحد التخطيطات الذاكرة في تلك الحقبة.




  • المقدمة

الذاكرة الفعلية هي مجموعة من العناوين الفيزيائية للخلايا الذاكرة التي يمكن للتطبيق أو نظام يخزن بياناته، رمز، وهلم جرا أثناء التنفيذ. إدارة الذاكرة يدل على إدارة هذه العناوين الفعلية عن طريق مبادلة البيانات من الذاكرة الفعلية إلى جهاز تخزين ومن ثم العودة إلى الذاكرة الفعلية عند الحاجة. نظام التشغيل بتنفيذ خدمات إدارة الذاكرة باستخدام الذاكرة الظاهرية. ونتيجة لC # مطور التطبيق لا تحتاج إلى كتابة أي خدمات إدارة الذاكرة. يستخدم CLR خدمات إدارة الذاكرة OS الأساسية لتقديم نموذج الذاكرة لC # أو أي لغة أخرى رفيعة المستوى تستهدف CLR.

ويبين الشكل 4-1 الذاكرة الفعلية التي تم استخراجها وإدارتها من قبل نظام التشغيل، وذلك باستخدام مفهوم الذاكرة الظاهرية. الذاكرة الظاهرية وجهة نظر مجردة من الذاكرة الفعلية، تدار من قبل نظام التشغيل. الذاكرة الظاهرية هو مجرد سلسلة من العناوين الظاهرية، ويتم ترجمة هذه العناوين الظاهرية عن طريق وحدة المعالجة المركزية إلى العنوان الفعلي عند الحاجة.

الشكل 4-1. CLR الذاكرة التجريد

يوفر CLR طبقة مجردة إدارة الذاكرة للبيئة تنفيذ الافتراضية، وذلك باستخدام خدمات الذاكرة العاملة. المفاهيم المستخرجة الاستخدامات CLR هي AppDomain، موضوع، المكدس، ملف heapmemorymapped، وهلم جرا. مفهوم مجال التطبيق (AppDomain) يعطي التطبيق الخاص بك بيئة تنفيذ معزولة.

  • التفاعل بين الذاكرة CLR وOS

من خلال النظر في تتبع المكدس في حين تصحيح C # التطبيق التالي، باستخدام WinDbg، سترى كيف يستخدم CLR خدمات إدارة الذاكرة OS الأساسية (على سبيل المثال، طريقة HeapFree من KERNEL32.DLL، وطريقة RtlpFreeHeap من NTDLL.DLL) لتنفيذ خاص نموذج الذاكرة:

using System;
namespace CH_04
{
    class Program
    {
        static void Main(string[] args)
        {
            Book book = new Book();
            Console.ReadLine();
        }
    }

    public class Book
    {
        public void Print() { Console.WriteLine(ToString()); }
    }
}

يتم تحميل التجميع المترجمة من البرنامج في WinDbg بدء التصحيح. يمكنك استخدام الأوامر التالية لتهيئة جلسة عمل التصحيح:

0: 000> SXE دينار clrjit

0: 000> ز

0: 000 CLR> .loadby استغاثة

0: 000> .load C: \ ويندوز \ Microsoft.NET \ الإطار \ v4.0.30319 \ sos.dll

بعد ذلك، يمكنك تعيين نقطة توقف في الأسلوب الرئيسي للطبقة البرنامج، وذلك باستخدام الأمر bpmd:

0: 000> bpmd CH_04.exe CH_04.Program.Main

لمتابعة التنفيذ وكسر في توقف تنفيذ الأمر ز:

0: 000> ز

عندما يكسر التنفيذ في نقطة توقف، يمكنك استخدام الأمر eestack! لعرض تفاصيل تتبع مكدس كل المواضيع الترشح للعملية الحالية. يظهر الإخراج التالي تتبع المكدس لجميع المواضيع الترشح لCH_04.exe التطبيق:

0: 000> eestack

الموضوع 0

الإطار الحالي: (MethodDesc 00233800 +0 CH_04.Program.Main (System.String []))

ChildEBP RetAddr المتصل، المستدعي

0022ed24 5faf21db CLR! CallDescrWorker + 0x33

/ النزرة إزالة /

0022f218 77712d68 ntdll! RtlFreeHeap + 0x142، داعيا ntdll! RtlpFreeHeap

0022f238 771df1ac KERNEL32! HeapFree + 0x14، داعيا ntdll! RtlFreeHeap

0022f24c 5fb4c036 CLR! EEHeapFree + 0x36، داعيا KERNEL32! HeapFree

0022f260 5fb4c09d CLR! EEHeapFreeInProcessHeap + 0x24، داعيا CLR! EEHeapFree

0022f274 5fb4c06d CLR! المشغل حذف [] + 0x30، داعيا CLR! EEHeapFreeInProcessHeap / أثر إزالة /

0022f4d0 7771316f ntdll! RtlpFreeHeap + 0xb7a، داعيا ntdll! _SEH_epilog4

0022f4d4 77712d68 ntdll! RtlFreeHeap + 0x142، داعيا ntdll! RtlpFreeHeap

0022f4f4 771df1ac KERNEL32! HeapFree + 0x14، داعيا ntdll! RtlFreeHeap

/ النزرة إزالة /

يشير هذا تتبع المكدس الذي يستخدمه CLR خدمات إدارة الذاكرة OS لتنفيذ نموذج الذاكرة الخاصة به. أي in.NET عملية الذاكرة يذهب عبر طبقة الذاكرة CLR إلى طبقة إدارة الذاكرة OS.

ويوضح الشكل 4-2 على C # نموذج الذاكرة تطبيق نموذجي المستخدمة من قبل CLR في وقت التشغيل.

الشكل 4-2 . نموذجي C نموذج الذاكرة # تطبيق

ويقترن نموذج الذاكرة CLR بإحكام مع خدمات إدارة الذاكرة OS. لفهم نموذج الذاكرة CLR، فمن المهم أن نفهم نموذج الذاكرة OS الأساسي. ومن المهم أيضا أن تعرف كيف تستخرج مساحة عنوان الذاكرة الفعلية إلى مساحة عنوان الذاكرة الظاهرية، الطرق يتم استخدام مساحة العنوان الظاهرية من قبل التطبيق المستخدم وتطبيق النظام، كيف الظاهري-لالبدنية يعمل تعيين عنوان، ذاكرة كيف يعمل ملف -mapped، وهلم جرا. وهذه المعرفة الخلفية تحسين فهم الخاص بك من المفاهيم نموذج الذاكرة CLR، بما في ذلك AppDomain، المكدس، وكومة.

لمزيد من المعلومات، يرجى الرجوع إلى هذا الكتاب:

C # تفكيكه: اكتشاف كيف C # يعمل على .NET Framework

هذا الكتاب + ClrViaC # + ويندوز الداخلية لل توجد موارد ممتازة لبرنامج .NET Framework المعروفة في العمق والعلاقة مع نظام التشغيل.




في التصنيف

ويستخدم كومة لتخصيص الذاكرة ثابت وكومة عن تخصيص الذاكرة الديناميكية، سواء مخزنة في ذاكرة الوصول العشوائي في جهاز الكمبيوتر.

بالتفصيل

المدخنة

كومة هو "LIFO" (آخر في، أولا الخروج) هيكل البيانات، التي يتم إدارتها والأمثل من قبل وحدة المعالجة المركزية بشكل وثيق جدا. في كل مرة وظيفة تعلن متغير جديد، هو "دفع" إلى المكدس. ثم في كل مرة يخرج وظيفة، كل من المتغيرات دفعت إلى المكدس من قبل تلك الوظيفة، يتم اطلاق سراح (وهذا يعني، يتم حذفها). مرة واحدة يتم تحرير متغير كومة، تصبح تلك المنطقة من الذاكرة المتوفرة للمتغيرات كومة أخرى.

وميزة استخدام مكدس لتخزين المتغيرات، هو أن الذاكرة تدار بالنسبة لك. لم يكن لديك تخصيص ذاكرة من جهة، أو تحريره مرة واحدة لا تحتاج أي أكثر من ذلك. ما هو أكثر من ذلك، لأن وحدة المعالجة المركزية تنظم مكدس الذاكرة بكفاءة، والقراءة من والكتابة إلى كومة متغيرات سريعة جدا.

أكثر يمكن العثور عليها هنا .

كومة

كومة هي منطقة من الذاكرة للكمبيوتر الخاص بك التي لا تدار تلقائيا بالنسبة لك، ولا تمكن بإحكام من قبل وحدة المعالجة المركزية. وهي منطقة أكثر عائمة خالية من الذاكرة (وهي أكبر). تخصيص الذاكرة على كومة، يجب عليك استخدام malloc () أو calloc ()، التي يتم بناؤها في وظائف C. وبمجرد الانتهاء من تخصيص الذاكرة على كومة، وكنت مسؤولا عن استخدام مجانا () لإلغاء تخصيص تلك الذاكرة مرة واحدة لا تحتاج أي أكثر من ذلك.

إذا فشلت في القيام بذلك، سوف برنامجك لديك ما يعرف باسم تسرب الذاكرة. وهذا هو، لا تزال الذاكرة على كومة أن تنحى جانبا (ولن تكون متاحة لعمليات أخرى). كما سنرى في قسم التصحيح، هناك أداة تسمى Valgrind التي يمكن أن تساعدك على كشف التسرب في الذاكرة.

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

وخلافا للكومة، والمتغيرات التي تم إنشاؤها على كومة يمكن الوصول إليها من قبل أي وظيفة في أي مكان في البرنامج. المتغيرات كومة عالمية أساسا في نطاق.

أكثر يمكن العثور عليها هنا .

يتم تخزين المتغيرات المخصصة على المكدس مباشرة إلى الذاكرة والوصول إلى هذه الذاكرة سريع جدا، ويتم التعامل مع تخصيص عندما يتم ترجمة البرنامج. عندما وظيفة أو وسيلة تدعو وظيفة أخرى وهذا بدوره يدعو وظيفة أخرى، وما إلى ذلك، وتنفيذ جميع هذه المهام يبقى معلقا حتى ترجع الدالة مشاركة جدا قيمته. محجوز كومة دائما في ترتيب LIFO، كتلة الأكثر محفوظة مؤخرا هو دائما كتلة المقبل سيتم اطلاق سراحهم. هذا يجعل من السهل حقا لتتبع المكدس، وتحرير كتلة من كومة ليس أكثر من تعديل مؤشر واحد.

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

يمكنك استخدام كومة إذا كنت تعرف بالضبط كم البيانات التي تحتاج إلى تخصيص قبل وقت الترجمة، وأنها ليست كبيرة جدا. يمكنك استخدام كومة إذا كنت لا تعرف بالضبط كم البيانات التي سوف تحتاج في وقت التشغيل أو إذا كنت تحتاج إلى تخصيص الكثير من البيانات.

في وضع متعددة الخيوط كل موضوع سوف يكون كومة مستقلة تماما الخاص بها، لكنها لن نشارك في الكومة. المكدس الخيط محددة وكومة هو تطبيق معين. المكدس المهم النظر في عمليات الإعدام معالجة الاستثناء والموضوع.

كل موضوع يحصل على كومة، في حين أن هناك عادة كومة واحدة فقط للتطبيق (على الرغم من أنه ليس من غير المألوف أن يكون أكوام متعددة لأنواع مختلفة من تخصيص).

في وقت التشغيل، إذا كان التطبيق يحتاج الى مزيد من كومة، فإنه يمكن تخصيص ذاكرة من الذاكرة الحرة، وإذا كانت كومة يحتاج الذاكرة، فإنه يمكن تخصيص ذاكرة من الذاكرة الحرة الذاكرة المخصصة للتطبيق.

حتى يتم إعطاء المزيد من التفاصيل هنا و هنا .

تأتي الآن و إجابات السؤال الخاص بك .

إلى أي مدى هم يسيطر عليها نظام التشغيل أو لغة وقت التشغيل؟

نظام التشغيل يخصص كومة لكل موضوع على مستوى النظام عند إنشاء موضوع. وعادة ما يطلق عليه نظام التشغيل من قبل وقت تشغيل اللغة تخصيص كومة للتطبيق.

أكثر يمكن العثور عليها هنا .

ما هو نطاقها؟

قدمت فعلا في القمة.

"يمكنك استخدام كومة إذا كنت تعرف بالضبط كم البيانات التي تحتاج إلى تخصيص قبل وقت الترجمة، وأنها ليست كبيرة جدا. يمكنك استخدام كومة إذا كنت لا تعرف بالضبط كم البيانات التي سوف تحتاج في وقت التشغيل أو إذا تحتاج إلى تخصيص الكثير من البيانات ".

أكثر يمكن العثور عليها في هنا .

ما الذي يحدد حجم كل منهم؟

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

ما يجعل المرء أسرع؟

تخصيص المكدس هو أسرع بكثير لأن كل ما يفعله حقا هو نقل مؤشر كومة. باستخدام حمامات الذاكرة، يمكنك الحصول على أداء مقارنة من تخصيص كومة الذاكرة المؤقتة، ولكن هذا يأتي مع تعقيد اضافي طفيف والصداع الخاصة بها.

أيضا، كومة مقابل كومة ليست مجرد النظر في الأداء؛ فإنه يخبرك أيضا الكثير عن العمر المتوقع من الكائنات.

تفاصيل ويمكن الاطلاع من هنا .




منذ بعض الإجابات ذهب نيتبيكينج، وانا ذاهب للمساهمة بلدي سوس.

والمثير للدهشة، وقد ذكر أحد أن متعددة (أي لا علاقة له عدد من تشغيل المواضيع على مستوى OS) والتي يمكن العثور عليها أكوام دعوة ليس فقط في لغات غريبة (بوست) أو منصات (إنتل إيتانيوم)، ولكن أيضا في الألياف ، المواضيع الخضراء وبعض تطبيقات coroutines .

الالياف والغزول الخضراء وcoroutines هي في نواح كثيرة مماثلة، الأمر الذي يؤدي إلى كثير من الالتباس. الفرق بين الألياف والخيوط الخضراء هو أن استخدام تعدد المهام التعاونية السابقة، في حين أن هذا الأخير قد تضم أي واحد تعاوني أو وقائية (أو حتى كليهما). للتمييز بين الألياف وcoroutines، انظر هنا .

في أي حال، فإن الغرض من كل من الألياف والخيوط والخضراء وcoroutines هو وجود وظائف متعددة المنفذة في وقت واحد، ولكن ليس في نفس الوقت (انظر هذا السؤال SO للتمييز) ضمن موضوع واحد على مستوى نظام التشغيل، ونقل السيطرة ذهابا وإيابا من واحد آخر في شكل منظم.

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

علما بأنني وقال " عادة ما يكون كومة منفصلة لكل وظيفة". هناك على حد سواء stackful و stackless تطبيقات couroutines. تطبيقات أبرز stackful C ++ هي Boost.Coroutine و مايكروسوفت PPL الصورة async/await. (ومع ذلك، C ++ الصورة ظائف قابلة للاستئناف (ويعرف أيضا باسم " asyncو await")، والتي تم طرحها على C ++ 17، ومن المرجح أن استخدام coroutines stackless).

الألياف اقتراح المكتبة القياسية C ++ وشيكة. أيضا، كنت هناك بعض طرف ثالث المكتبات . المواضيع الخضراء هي شعبية جدا في لغات مثل بايثون وروبي.




وقبل بضعة سنتات: أعتقد أنه سيكون جيدا لرسم بياني الذاكرة وأكثر بساطة:


سهام - المعرض حيث تنمو كومة كومة و، عملية حجم كومة لها حد، المحددة في نظام التشغيل، موضوع كومة حدود حجم من قبل المعلمات في موضوع خلق API عادة. كومة عادة ما يحد من الحد الأقصى لحجم الذاكرة الظاهرية العملية، لمدة 32 بت 2-4 GB على سبيل المثال.

بسيطة جدا الطريقة: كومة العملية العامة للعملية وجميع المواضيع داخل، وذلك باستخدام لتخصيص الذاكرة في حالة مشتركة مع شيء من هذا القبيل malloc () .

كومة من ذاكرة سريعة لتخزين في حالة شائعة مؤشرات الدالة العودة والمتغيرات، معالجة كمعلمات في استدعاء دالة، المتغيرات وظيفة المحلية.




كومة ، كومة و البيانات لكل عملية في الذاكرة الظاهرية:




OK، ببساطة وبعبارة قصيرة، فإنها تعني أمر و لم يؤمر !

كومة : في البنود المكدس، الامور على رأس كل منهما الآخر،، يعني سيصبح أسرع وأكثر كفاءة لتتم معالجتها ...

حتى لا يكون هناك دائما المؤشر إلى نقطة عنصر معين، وتجهيز أيضا سيصبح أسرع، وهناك علاقة بين العناصر كذلك! ...

كومة : لا النظام، ومعالجة ستعمل تكون أبطأ وافسدت القيم معا بدون ترتيب معين أو مؤشر ... هناك عشوائية وعدم وجود علاقة بينهما ... لذلك التنفيذ واستخدام الوقت يمكن أن تختلف ...

أنا أيضا إنشاء الصورة أدناه لإظهار الكيفية التي قد تبدو مثل:




وهناك الكثير من الأجوبة صحيحة كمفاهيم، ولكن يجب أن نلاحظ أن هناك حاجة إلى كومة من قبل الأجهزة (أي المعالج) للسماح يدعو الوظائف الفرعية (CALL في لغة التجميع ..). (الرجال OOP سوف يطلق عليه أساليب )

على المكدس تقوم بحفظ العودة عناوين وندعو تدار → دفع / المتقاعد → البوب ​​مباشرة في الأجهزة.

يمكنك استخدام كومة لتمرير المعلمات .. حتى لو كان أبطأ من استخدام سجلات (أن يقول المعلم المعالج أو 1980s جيدة كتاب BIOS ...)

  • دون كومة لا المعالج يمكن أن تنجح. (لا يمكننا أن نتصور البرنامج، حتى في لغة التجميع، دون الوظائف الفرعية / وظائف)
  • دون كومة ما في وسعها. (برنامج لغة التجميع يمكن أن تعمل دون، وكومة هو مفهوم OS، كما malloc، وهذا هو OS / دعوة ليب.

استخدام كومة أسرع على النحو التالي:

  • هل الأجهزة، وحتى دفع / البوب ​​وفعالة جدا.
  • malloc يتطلب تدخل وضع kernel، استخدام قفل / إشارة (أو غيرها من الأوليات التزامن) تنفيذ بعض التعليمات البرمجية وإدارة بعض الهياكل اللازمة لتتبع التخصيص.



لدي شيء لأشاطركم، على الرغم من النقاط الرئيسية التي صاغها بالفعل.

كومة

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

كومة

  • وصول بطيئة نسبيا إلى المكدس.
  • المخزنة في ذاكرة الوصول العشوائي.
  • يتم تخزين متغيرات إنشاؤه بشكل حيوي هنا، الأمر الذي يتطلب في وقت لاحق تحرير الذاكرة المخصصة بعد الاستعمال.
  • المخزنة أينما يتم تخصيص الذاكرة، الوصول إليها من قبل مؤشر دائما.

ملاحظة مثيرة للاهتمام:

  • يجب أن تم تخزين المكالمات وظيفة في كومة، فإنه أدى إلى 2 نقطة فوضوي:
    1. بسبب التخزين متتابعة في كومة والتنفيذ أسرع. قد أدى تخزين في كومة في استهلاك الوقت ضخم مما أدى برنامج كامل لتنفيذ أبطأ.
    2. إذا تم تخزينها وظائف في كومة (تخزين فوضوي وأشار من قبل المؤشر)، لما كان هناك أي وسيلة للعودة إلى عنوان المتصل الظهر (التي كومة يعطي بسبب التخزين متتابعة في الذاكرة).

وwellcomed المرتدة.