إدارة الذاكرة في TypeScript: كيف يعمل جامع القمامة

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

الذاكرة وجامع القمامة في TypeScript: ما الذي يحدث خلف الكواليس؟

\n\n

تخيل أنك تبني منزلاً. تشتري الطوب والأسمنت والحديد - ولكن إذا لم تقم بإزالة مخلفات البناء، فسرعان ما تتحول موقع البناء إلى مكب نفايات. نفس الشيء يحدث في كود TypeScript الخاص بك. تقوم بإنشاء كائنات، مصفوفات، إغلاقات - وإذا لم تقم بتحرير الذاكرة في الوقت المناسب، يبدأ التطبيق في التباطؤ، ثم يتعطل تمامًا مع خطأ Out of Memory.

\n\n

في هذه المقالة، سنحلل كيفية عمل إدارة الذاكرة في TypeScript وأداتها الرئيسية - جامع القمامة. ستتعرف على الآليات التي تقف وراء تحرير الذاكرة، وكيفية تجنب التسربات، ولماذا قد يستهلك كودك ميغابايتات حتى بعد التوقف عن استخدامه.

\n\n

هيا بنا!

\n\n

كيف يدير TypeScript الذاكرة؟ الأساسيات

\n\n

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

\n\n

في JavaScript، تنقسم الذاكرة إلى منطقتين رئيسيتين:

\n\n
    \n
  • المكدس (Stack) - يخزن البدائيات (الأرقام، السلاسل النصية، القيم المنطقية) والمراجع إلى الكائنات. يتم تحريره تلقائيًا عند الخروج من الدالة.
  • \n
  • الكومة (Heap) - تخزن الكائنات، المصفوفات، الدوال. هنا يعمل جامع القمامة.
  • \n
\n\n

عندما تكتب:

\n\n
const user = { name: 'Alice', age: 30 };
\n\n

المتغير user يُخزن في المكدس ويحتوي على مرجع للكائن في الكومة. طالما يوجد مرجع - الكائن حي. بمجرد اختفاء المرجع - يصبح الكائن "قمامة".

\n\n

جامع القمامة في TypeScript: كيف يعمل؟

\n\n

جامع القمامة (Garbage Collector, GC) هو عملية تلقائية تجد الكائنات التي لم يعد لها مراجع، وتحرر الذاكرة التي تشغلها. تستخدم المحركات الحديثة (V8 في Chrome، SpiderMonkey في Firefox) خوارزميات معقدة، لكن الأساس هو خوارزمية الوسم والكنس (Mark-and-Sweep).

\n\n

كيف يعمل هذا:

\n\n
    \n
  1. يبدأ GC من "الجذور" - الكائنات العامة، المتغيرات المحلية في الدوال التي يتم تنفيذها.
  2. \n
  3. يمر عبر جميع المراجع من الجذور ويوسم كل كائن يمكن الوصول إليه.
  4. \n
  5. جميع الكائنات غير الموسومة تعتبر قمامة ويتم حذفها.
  6. \n
\n\n

يبدو الأمر بسيطًا، لكن في الممارسة هناك تفاصيل دقيقة. على سبيل المثال، المراجع الدائرية:

\n\n
function createCycle() {\n    const obj1: any = {};\n    const obj2: any = {};\n    obj1.ref = obj2;\n    obj2.ref = obj1;\n    return 'done';\n}
\n\n

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

\n\n

تسربات الذاكرة النموذجية في تطبيقات TypeScript

\n\n

حتى مع وجود جامع قمامة ذكي، يمكنك "الوقوع في الفخ". إليك السيناريوهات الأكثر شيوعًا التي تؤدي إلى تسربات الذاكرة في TypeScript:

\n\n

1. المؤقتات المنسية ومعالجات الأحداث

\n\n

أحد الأسباب الأكثر شيوعًا. لقد اشتركت في حدث، ونسيت إلغاء الاشتراك:

\n\n
class TimerComponent {\n    private intervalId: number;\n\n    start() {\n        this.intervalId = window.setInterval(() => {\n            console.log('Tick');\n        }, 1000);\n    }\n\n    // نسيت استدعاء stop() - المؤقت سيعيش إلى الأبد!\n}
\n\n

الحل: قم دائمًا بتنظيف المؤقتات وإلغاء الاشتراك من الأحداث في طريقة dispose أو ngOnDestroy (لـ Angular).

\n\n

2. الإغلاقات التي تحتفظ بالمراجع

\n\n

الإغلاقات أداة قوية، لكنها قد تحتفظ بشكل غير مقصود بكائنات ضخمة:

\n\n
function createHeavyClosure() {\n    const hugeData = new Array(1000                

المدونات

توصيات الكتب