عدّ المراجع في CPython
افهم كيفية تتبّع CPython لأعمار الكائنات باستخدام أعداد المراجع
عدّ المراجع في CPython درس مجاني في Python Academy على CoddyKit. هذا هو الدرس 1 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Python Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Python Academy 4 دروس في المجموع.
ما هو عدّ المراجع؟
تتتبّع CPython عدد مراجع كل كائن. وعندما ينخفض العدد إلى 0، يُزال تخصيص الكائن فورًا. وهذه هي آلية Python الأساسية لإدارة الذاكرة.
import sys
x = [1, 2, 3]
print(sys.getrefcount(x)) # 2 (x + getrefcount arg)
y = x
print(sys.getrefcount(x)) # 3sys.getrefcount()
تعيد sys.getrefcount(obj) عدد المراجع الحالي. ملاحظة: يؤدي استدعاؤها إلى إضافة 1، بسبب مرجع وسيط الدالة.
import sys
a = "hello"
print(sys.getrefcount(a)) # baseline (may be high for interned strings)
b = a
print(sys.getrefcount(a)) # one more
del b
print(sys.getrefcount(a)) # back to baselineالزيادة والنقصان
تزيد كل عملية إسناد العدد، بينما تنقصه كل عملية حذف أو إعادة إسناد. وعندما يصل العدد إلى 0، تستدعي CPython مزيل تخصيص الكائن.
x = [] # refcount = 1
y = x # refcount = 2
z = [x] # refcount = 3 (list holds a reference)
del y # refcount = 2
z.clear() # refcount = 1
del x # refcount = 0 → deallocatedتضمين الكائنات
تضمّن CPython الأعداد الصحيحة الصغيرة (من -5 إلى 256) والعديد من القيم النصية الحرفية، فتُعيد استخدام الكائن نفسه. وتكشف مقارنات is عن ذلك.
a = 256
b = 256
print(a is b) # True (interned)
c = 257
d = 257
print(c is d) # may be False (not interned)المراجع الضعيفة
لا تزيد المراجع الضعيفة عدد المراجع. وهي مفيدة لتجنب منع جمع البيانات المهملة للكائنات التي تريد مراقبتها دون امتلاكها.
import weakref
class BigObject:
pass
obj = BigObject()
ref = weakref.ref(obj)
print(ref()) # <BigObject instance>
del obj
print(ref()) # None (object was collected)دورات المراجع
إذا كان A يشير إلى B وكان B يشير إلى A، فلن يصل أي منهما إلى 0 حتى عندما يتعذر الوصول إلى كليهما. تكتشف أداة جمع البيانات المهملة الدورية في CPython هذه الدورات وتجمعها.
a = []
b = [a]
a.append(b) # cycle: a → b → a
del a, b
# Both are unreachable but refcount > 0
# The cyclic GC collects themالوحدة gc
توفر الوحدة gc أداة جمع البيانات المهملة الدورية. وهي تعمل تلقائيًا، لكن يمكن تشغيلها يدويًا أو تعطيلها.
import gc
gc.collect() # force a collection cycle
print(gc.get_count()) # (gen0, gen1, gen2) allocation counts
print(gc.get_threshold()) # when each generation is collectedتجمعات الذاكرة (pymalloc)
تخصّص CPython الكائنات الصغيرة (أقل من 512 بايت) من تجمع الذاكرة الخاص بها (pymalloc)، وهو أسرع من استدعاء malloc لكل كائن صغير.
# You do not call pymalloc directly — CPython uses it internally
# for all Python-level object allocations
# The pool pre-allocates large memory arenas
# and carves them into pools of fixed-size blocksالمنهيات __del__
يُستدعى __del__ عندما يصل عدد مراجع الكائن إلى 0، أو لاحقًا إذا كان الكائن ضمن دورة. تجنّب الاعتماد عليه للتنظيف المهم — واستخدم مديري السياق بدلًا منه.
class Resource:
def __del__(self):
print(f"Freeing {self}")
# Better: use context manager
class SafeResource:
def __enter__(self): return self
def __exit__(self, *a): self.cleanup()كائنات مدمجة باستخدام __slots__
تستخدم الكائنات التي تحتوي على __slots__ ذاكرة أقل وعمليات تخصيص أقل، مما يقلل الضغط على GC.
import sys
class Reg:
def __init__(self, x, y): self.x, self.y = x, y
class Slotted:
__slots__ = ("x","y")
def __init__(self, x, y): self.x, self.y = x, y
print(sys.getsizeof(Reg(1,2))) # ~48 + dict overhead
print(sys.getsizeof(Slotted(1,2))) # ~48 (no dict)تعطيل أداة GC الدورية
بالنسبة إلى البرامج التي لا تنشئ دورات مراجع، قد يؤدي تعطيل أداة GC الدورية إلى تحسين معدل المعالجة.
import gc
gc.disable() # no cyclic GC — objects are only freed by refcounting
# Use only if you KNOW no cycles are created
# (pure functional/immutable data)
gc.enable() # re-enableتحقق سريع
متى تزيل CPython تخصيص كائن فورًا؟
مراجعة
تتتبّع CPython الكائنات باستخدام أعداد المراجع. ويؤدي وصول العدد إلى 0 إلى إزالة التخصيص فورًا. وتعالج أداة GC الدورية دورات المراجع عبر الوحدة gc. تجنّب استخدام __del__ للتنظيف المهم؛ واستخدم مديري السياق. استخدم __slots__ لتقليل الذاكرة المستخدمة لكل كائن.
الأسئلة الشائعة
هل درس «عدّ المراجع في CPython» مجاني؟
نعم — نص درس «عدّ المراجع في CPython» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Python Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Python Academy 4 دروس في المجموع.
ماذا ستتعلم في «عدّ المراجع في CPython»؟
افهم كيفية تتبّع CPython لأعمار الكائنات باستخدام أعداد المراجع تتمرن على Python Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ Python Academy؟
لا تُشترط خبرة سابقة. Python Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 1 من أصل 4.
كم من الوقت يستغرق درس «عدّ المراجع في CPython»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس Python Academy هذا؟
نعم. كل درس في Python Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- عدّ المراجع في CPython
- جامع البيانات المهملة والمراجع الدورية
- تحليل الأداء باستخدام cProfile وline_profiler
- تحليل الذاكرة باستخدام tracemalloc