0Pricing
Python Academy · درس

جامع البيانات المهملة والمراجع الدورية

تعلّم كيفية تعامل الوحدة gc مع دورات المراجع

جامع البيانات المهملة والمراجع الدورية درس مجاني في Python Academy على CoddyKit. هذا هو الدرس 2 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Python Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Python Academy 4 دروس في المجموع.

لماذا لا يكفي عدّ المراجع؟

لا يستطيع عدّ المراجع جمع الكائنات المشاركة في دورات مراجع؛ إذ يحتفظ كل كائن بمرجع إلى الآخر، ولذلك لا ينخفض أي من العددين إلى 0.

# Reference cycle: a → b → a
a = {}
b = {"other": a}
a["other"] = b
del a, b
# Both objects are unreachable but refcount > 0
# Only the cyclic GC can collect them

الوحدة gc

gc هي أداة جمع البيانات المهملة الدورية. تفحص دوريًا الكائنات المتتبعة بحثًا عن الدورات غير القابلة للوصول، ثم تجمعها.

import gc

gc.collect()   # trigger immediately
print(gc.garbage)   # objects with __del__ in cycles (cannot auto-collect)

الجمع حسب الأجيال

تستخدم أداة GC ثلاثة أجيال. تبدأ الكائنات الجديدة في الجيل 0. وتُنقل الكائنات التي تنجو من عملية جمع إلى جيل أعلى. ويُجمع الجيل 0 بأكبر تكرار.

import gc

print(gc.get_count())     # (gen0, gen1, gen2) allocations since last collection
print(gc.get_threshold()) # (700, 10, 10) — thresholds for each generation
gc.set_threshold(1000, 15, 10)  # tune

اكتشاف الدورات باستخدام gc.get_referents

افحص الكائنات التي يشير إليها كائن ما — فهذا مفيد لفهم سبب عدم جمع كائن معين.

import gc

a = []
b = [a]
a.append(b)

for ref in gc.get_referents(a):
    print(ref)   # shows b

gc.get_objects()

تعيد gc.get_objects() جميع الكائنات التي تتتبعها أداة GC حاليًا. وهي مفيدة للعثور على تسربات الذاكرة.

import gc

before = len(gc.get_objects())
create_lots_of_objects()
after = len(gc.get_objects())
print(f"Leaked: {after - before} objects")

تجنب الدورات

صمّم هياكل البيانات لتجنب الدورات: استخدم weakrefs للمراجع العكسية، أو استخدم المعرّفات بدلًا من المراجع المباشرة، أو اكسر الدورات صراحةً قبل خروج الكائنات من النطاق.

import weakref

class Node:
    def __init__(self, parent):
        # weakref avoids cycle:
        self.parent = weakref.ref(parent)

class Tree:
    def __init__(self):
        self.child = Node(self)   # no hard cycle

__del__ والدورات

لا يمكن جمع الكائنات التي تحتوي على __del__ وتشارك في دورة تلقائيًا. بل توضع في gc.garbage بدلًا من ذلك.

import gc

class Leaky:
    def __del__(self): pass

a = Leaky()
b = Leaky()
a.other = b
b.other = a
del a, b

gc.collect()
print(gc.garbage)   # [Leaky, Leaky] — cannot collect

gc.freeze() — Python 3.7 فما بعد

تجمّد gc.freeze() الكائنات المتتبعة حاليًا، بحيث لا تُجمع أبدًا. وهي مفيدة في العمليات طويلة التشغيل بعد بدء التشغيل لتقليل فترات توقف GC.

import gc

# After all globals and imports are in place:
gc.freeze()   # no GC scanning for these objects ever again

# Useful for: gunicorn pre-fork, background servers

تعطيل GC وإعادة تمكينها

عطّل أداة GC الدورية في الحلقات الضيقة التي تعرف أنه لا توجد فيها دورات، ثم أعد تمكينها وافرِض إجراء عملية جمع بعدها.

import gc

gc.disable()
try:
    result = tight_loop_no_cycles()
finally:
    gc.enable()
    gc.collect()

isenabled وisfinalized

تحقّق من حالة GC باستخدام gc.isenabled()، واكتشف ما إذا كان يجري إنهاء كائن باستخدام gc.is_finalized(obj).

import gc

print(gc.isenabled())      # True by default
obj = object()
print(gc.is_finalized(obj))  # False (still alive)

أنماط تسرب الذاكرة

من الأسباب الشائعة لتسرب الذاكرة في Python: ذاكرات التخزين المؤقت العامة التي تنمو بلا حدود، ومستمعو الأحداث الذين لم يُفصلوا، والمراجع الدورية التي تحتوي على __del__، وامتدادات C التي تسرّب المراجع.

# Typical leaks:
global_cache = {}   # grows forever — use lru_cache with maxsize

class EventBus:
    listeners = []
    # Listeners hold references to objects:
    # @classmethod
    # def on(cls, fn): cls.listeners.append(fn)
    # Must call off() to detach

تحقق سريع

ماذا يحدث للكائنات التي تحتوي على __del__ وتشارك في دورة مراجع؟

مراجعة

تعالج أداة GC الدورية دورات المراجع التي لا يستطيع عدّ المراجع التعامل معها. وتستخدم ثلاثة أجيال، وتنقل الكائنات الناجية إلى أجيال أعلى. تجنّب الدورات باستخدام weakrefs. وتوضع الكائنات التي تحتوي على __del__ ضمن دورات في gc.garbage. استخدم gc.freeze() بعد بدء التشغيل لتقليل فترات توقف GC في الخوادم طويلة التشغيل.

الأسئلة الشائعة

هل درس «جامع البيانات المهملة والمراجع الدورية» مجاني؟

نعم — نص درس «جامع البيانات المهملة والمراجع الدورية» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Python Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Python Academy 4 دروس في المجموع.

ماذا ستتعلم في «جامع البيانات المهملة والمراجع الدورية»؟

تعلّم كيفية تعامل الوحدة gc مع دورات المراجع تتمرن على Python Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ Python Academy؟

لا تُشترط خبرة سابقة. Python Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 2 من أصل 4.

كم من الوقت يستغرق درس «جامع البيانات المهملة والمراجع الدورية»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس Python Academy هذا؟

نعم. كل درس في Python Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. عدّ المراجع في CPython
  2. جامع البيانات المهملة والمراجع الدورية
  3. تحليل الأداء باستخدام cProfile وline_profiler
  4. تحليل الذاكرة باستخدام tracemalloc
← العودة إلى Python Academy