إدارة الذاكرة وضبط GC
تعمّق في إدارة ذاكرة JVM وجمع البيانات المهملة وتقنيات تحسين استخدام الذاكرة في Scala
إدارة الذاكرة وضبط GC درس مجاني في Scala for Backend Engineering & Functional Programming على CoddyKit. هذا هو الدرس 2 من أصل 3. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Scala for Backend Engineering & Functional Programming، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Scala for Backend Engineering & Functional Programming 3 دروس في المجموع.
مقدمة إلى ذاكرة JVM وGC
مرحبًا! في هذا الدرس، سنتعمق في كيفية إدارة Java Virtual Machine (JVM) للذاكرة، وهو أمر بالغ الأهمية خصوصًا لتطبيقات Scala.
- يساعدك فهم الذاكرة في كتابة كود فعّال وعالي الأداء.
- سنستكشف Garbage Collection (GC)، وهو مدير الذاكرة التلقائي في JVM.
- تمنع الإدارة السليمة للذاكرة مشكلات شائعة مثل أخطاء نفاد الذاكرة.
الـ Heap: تخزين الكائنات
يُعد Heap أكبر منطقة ذاكرة في JVM، حيث توجد جميع الكائنات التي ينشئها تطبيق Scala. ويشمل ذلك مثيلات الفئات والمصفوفات ومعظم هياكل البيانات.
تتشارك جميع الخيوط في تطبيقك في الـ Heap. ويؤثر حجمه مباشرةً في عدد الكائنات التي يستطيع برنامجك الاحتفاظ بها في الوقت نفسه.
الفرق بين Stack وHeap
بينما يحتفظ الـ Heap بالكائنات، يخزّن Stack المتغيرات المحلية، ولا سيما الأنواع البدائية ومراجع الكائنات، بالإضافة إلى إطارات استدعاءات الأساليب. ولكل خيط Stack خاص به.
- Heap: يخزّن الكائنات، وهو مشترك وتديره GC.
- Stack: يخزّن استدعاءات الأساليب والمتغيرات المحلية، وهو خاص بكل خيط وتتم إدارته تلقائيًا عند دخول الأساليب وخروجها.
يُعد فهم هذا الفرق أساسيًا لتصحيح مشكلات الذاكرة.
أساسيات Garbage Collection
إن Garbage Collection (GC) عملية تلقائية في JVM للعثور على الذاكرة التي تشغلها الكائنات التي لم يعد التطبيق قادرًا على الوصول إليها واستعادتها.
بدلًا من تحرير الذاكرة يدويًا، كما في C++، تعتمد Scala (وJava) على GC لمنع تسرّبات الذاكرة وتبسيط التطوير. والفكرة الأساسية هي "التعليم والمسح": علّم الكائنات التي يمكن الوصول إليها، ثم امسح ما تبقى.
شرح GC التوليدي
تستخدم معظم عمليات GC الحديثة نهجًا توليديًا يقسّم الـ Heap إلى مناطق استنادًا إلى عمر الكائن:
- التوليد الفتي: حيث تُخصّص الكائنات الجديدة. تموت معظم الكائنات وهي في هذه المرحلة.
- التوليد القديم: تنتقل إليه الكائنات التي تنجو من عمليات GC متعددة في التوليد الفتي.
يسمح ذلك بإجراء عمليات GC أكثر تكرارًا وأسرع على التوليد الفتي (Minor GC)، وعمليات أقل تكرارًا وأبطأ على التوليد القديم (Major GC).
مجموعات Scala والذاكرة
غالبًا ما يؤدي تركيز Scala على عدم القابلية للتغيير والبرمجة الوظيفية إلى إنشاء العديد من الكائنات قصيرة العمر، خصوصًا أثناء تحويلات المجموعات.
تم تحسين GC للتعامل مع ذلك. لنرَ مثالًا على إنشاء كائن مؤقت أثناء معالجة قائمة:
object Main {
def main(args: Array[String]): Unit = {
println("Creating and transforming a list...")
val originalList = (1 to 100000).toList // ~100k objects
val transformedList = originalList.map(x => x * 2).filter(_ % 3 == 0)
println(s"Transformed list size: ${transformedList.size}")
// originalList and intermediate lists from map are now eligible for GC
println("Intermediate objects are efficiently managed by GC.")
}
}حالات شائعة لتسرّب الذاكرة
حتى مع GC، قد تحدث تسرّبات للذاكرة عندما تُبقي مراجع قوية الكائنات حيّة دون قصد. ومن الحالات الشائعة في Scala:
- ذاكرات التخزين المؤقت طويلة العمر: تخزين الكائنات إلى أجل غير مسمى في خريطة عامة قابلة للتغيير.
- الإغلاقات: إغلاق، أي دالة حرفية، يلتقط كائنًا كبيرًا يتجاوز عمره النطاق المقصود للإغلاق.
- الموارد غير المغلقة: عدم إغلاق مقابض الملفات أو اتصالات الشبكة بطريقة صحيحة.
المراجع الضعيفة للتخزين المؤقت
بالنسبة إلى ذاكرات التخزين المؤقت التي تريد أن تستعيد GC ذاكرتها إذا كان الكائن لا يُشار إليه إلا من ذاكرة التخزين المؤقت، استخدم java.lang.ref.WeakReference.
لا يمنع WeakReference جمع الكائن الذي يشير إليه بواسطة Garbage Collection. وإذا كانت المراجع المتبقية الوحيدة إلى كائن ما هي مراجع ضعيفة، يصبح الكائن مؤهلًا لـ GC.
import java.lang.ref.WeakReference
object Main {
def main(args: Array[String]): Unit = {
var largeData: Array[Byte] = new Array[Byte](1024 * 1024) // 1MB
val weakCacheEntry = new WeakReference(largeData)
println(s"Data exists via weak ref: ${weakCacheEntry.get() != null}")
largeData = null // Remove the strong reference
System.gc() // Hint to the JVM to run GC
Thread.sleep(100) // Give GC time to run
println(s"Data collected (possibly): ${weakCacheEntry.get() == null}")
println("WeakReference allows GC to clean up if no strong references remain.")
}
}أعلام JVM الأساسية لضبط GC
رغم أن GC تلقائي، يمكنك ضبط سلوكه باستخدام وسيطات JVM. وتشمل الأعلام الأساسية ما يلي:
-Xmx: يحدّد الحد الأقصى لحجم Java heap، مثل-Xmx4gلأربعة غيغابايت.-Xms: يحدّد الحجم الابتدائي لـ Java heap، مثل-Xms512mلـ512 ميغابايت.-XX:+UseG1GC: يحدّد جامع Garbage-First (G1)، وهو خيار حديث شائع.
قد يؤثر ضبط هذه الأعلام بدرجة كبيرة في أداء التطبيق واستخدام الذاكرة.
تحقق من فهمك
أي العبارات التالية حول إدارة ذاكرة JVM وGarbage Collection صحيحة؟
مراجعة: الذاكرة وGC
أحسنت! لقد استكشفت أساسيات إدارة ذاكرة JVM وGarbage Collection:
- يحتوي Heap على الكائنات، بينما يحتوي Stack على استدعاءات الأساليب والمتغيرات المحلية.
- تستعيد GC تلقائيًا الذاكرة من الكائنات التي لم يعد بالإمكان الوصول إليها.
- يساعد فهم GC التوليدي (التوليدين الفتي والقديم) في تحسين الأداء.
- انتبه إلى تسرّبات الذاكرة، واستخدم أدوات مثل WeakReference لاحتياجات التخزين المؤقت المحددة.
- تتحكم أعلام JVM الأساسية مثل
-Xmxو-Xmsفي حجم الـ heap.
بعد ذلك، سنتعمق في أدوات تحليل الأداء لتحديد أعناق الزجاجة!
الأسئلة الشائعة
هل درس «إدارة الذاكرة وضبط GC» مجاني؟
نعم — نص درس «إدارة الذاكرة وضبط GC» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Scala for Backend Engineering & Functional Programming، انتقل إلى CoddyKit PRO. تتضمن دورة Scala for Backend Engineering & Functional Programming 3 دروس في المجموع.
ماذا ستتعلم في «إدارة الذاكرة وضبط GC»؟
تعمّق في إدارة ذاكرة JVM وجمع البيانات المهملة وتقنيات تحسين استخدام الذاكرة في Scala تتمرن على Scala for Backend Engineering & Functional Programming مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ Scala for Backend Engineering & Functional Programming؟
لا تُشترط خبرة سابقة. Scala for Backend Engineering & Functional Programming على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 2 من أصل 3.
كم من الوقت يستغرق درس «إدارة الذاكرة وضبط GC»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس Scala for Backend Engineering & Functional Programming هذا؟
نعم. كل درس في Scala for Backend Engineering & Functional Programming يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- تحليل أداء تطبيقات Scala
- إدارة الذاكرة وضبط GC
- تحسين التعليمات البرمجية المتزامنة