Tutorial Material

Xotira boshqaruvi (memory management)

Share to
Python memory management

Python ommabop bo'lishining sabablaridan biri — dasturchi C yoki C++ dagidek qo'lda xotira boshqaruvi (memory management) bilan shug'ullanishi shart emas. Python xotira ajratish (allocation) va bo'shatishni (deallocation) avtomatik bajaradi.

Shunga qaramay, Python xotirani ichkarida qanday boshqarishini tushunish samarali kod yozish uchun muhim, ayniqsa katta ma'lumotlar bilan ishlaganda.

1. Heap va Stack

Python ikki xil xotiradan foydalanadi:

2. Reference counting

Python xotira boshqaruvidagi asosiy strategiya — reference counting.

Har bir obyektning reference count'i bo'ladi: nechta nom yoki tuzilma o'sha obyektga ishora qilayotganini bildiradi.

import sys

a = []
# Referens sonini olish (kutilganidan yuqori bo'lishi mumkin, chunki sys.getrefcount'ning argumenti ham vaqtinchalik referens)
print(sys.getrefcount(a)) 

b = a
print(sys.getrefcount(a)) # Increases

del b
print(sys.getrefcount(a)) # Decreases

3. Garbage collection (GC)

Reference counting'ning bitta muammosi bor: aylanma referenslar (circular references).

a = []
b = []
a.append(b)
b.append(a) # Circular reference

Agar a va b o'chirilsa ham, ular bir-biriga ishora qilgani uchun reference count hech qachon 0 bo'lmaydi. Shu yerda Garbage Collector (GC) ishga tushadi.

Python GC alohida mexanizm bo'lib, vaqti-vaqti bilan ishlaydi va aylanma referenslardan hosil bo'lgan "garbage"ni topib tozalaydi.

GC'ni gc moduli bilan qo'lda boshqarish mumkin:

import gc

# Garbage collection'ni majburan ishga tushirish
gc.collect()

# Avtomatik garbage collection'ni o'chirish
gc.disable()

Maslahat: odatda gc moduliga kamdan-kam teginasiz, asosan yuqori darajali optimizatsiya uchun kerak bo'ladi.

4. Xotirani tejash bo'yicha maslahatlar

  1. Generator ishlating: oldingi darsda ko'rganimizdek, generator hamma ma'lumotni RAM'ga yuklamaydi.
  2. Class'larda __slots__ ishlating: agar kichik class'dan millionlab instance yaratsangiz, __slots__ har bir instance uchun dinamik __dict__ni o'chirib, RAM'ni tejaydi.
class SaveMemory:
    __slots__ = ['name', 'age'] # Can only have these attributes
    def __init__(self, name, age):
        self.name = name
        self.age = age
  1. Global o'zgaruvchilarga ehtiyot bo'ling: global obyektlar dastur to'xtamaguncha o'chmaydi (qo'lda o'chirmasangiz).

5. Identiklik (identity) va tenglik (equality)

Ikkita o'zgaruvchi teng qiymatlarni saqlashi mumkin, lekin xotirada turli obyektlar bo'lishi mumkin. == qiymatlarni solishtiradi; is identiklikni (xuddi o'sha obyekt ekanini) solishtiradi. id() obyektning xotira manzilini qaytaradi.

a = [1, 2, 3]
b = [1, 2, 3]
c = a

print(a == b)   # True  (bir xil tarkib)
print(a is b)   # False (ikkita alohida obyekt)
print(a is c)   # True  (c xuddi a kabi listga ishora qiladi)

print(id(a) == id(c))   # True

6. Kichik obyektlarni interning qilish

Xotirani tejash uchun CPython ba'zi immutable obyektlarni qayta ishlatadi (intern qiladi) — kichik butun sonlar (taxminan −5 dan 256 gacha) va ko'p qisqa stringlar bitta nusxani baham ko'radi:

x = 100
y = 100
print(x is y)   # True  (kichik int'lar keshlanadi)
>>> m = 1000
>>> n = 1000
>>> m is n   # ko'pincha False: 1000 CPython'ning kichik-int keshidan tashqarida (-5..256)
False

Eslatma: Sonlar yoki stringlar kabi qiymatlarni solishtirish uchun hech qachon is ishlatmang — interning bu amalga oshirish tafsiloti. is'ni faqat None kabi singleton'lar uchun ishlating: if value is None:.

Xulosa