Мазмунга өтүү

Эстекти башкаруу жана таштандыны чогултуу

Сабактын башталышы

Эстекти башкаруу жана таштандыны чогултуу

CPython аткаруу учурунда объекттерди кантип бөлүштүрөт, көзөмөлдөйт жана бошотот

Негизги идея: CPython эстекти эки кызматташкан механизм менен бошотот. Шилтемелерди эсептөө объектке эч ким шилтебей калган заматта аны бошотот; циклдик таштанды чогултуучу болсо шилтемелерди эсептөө чече албаган жалгыз учур үчүн гана бар — бири-бирине шилтеме кылган, бирок сиздин кодуңуздан жетүүгө мүмкүн болбогон объекттердин топтору үчүн. Ар бир механизм кайдан башталып, кайдан токтоорун түшүнүү — агып кетүүлөр, финализаторлордун иреттиги жана узак иштеген кызматтын эстек профили жөнүндө ой жүгүртүүгө мүмкүндүк берет.
Аягында сиз төмөнкүлөрдү аткара аласыз:
  • шилтемелерди эсептөө объекттин качан бошотуларын кантип чечерин жана эмне үчүн sys.getrefcount ар дайым бирге көбүрөөк көрсөтөрүн түшүндүрүү;
  • циклдик шилтемелер таза эсептөөнү кантип айланып өтөрүн жана муундук чогултуучу аларды кантип бошотоорун сүрөттөө;
  • объектти тирүү кармабай туруп аны байкоо же кэштөө үчүн weakref колдонуу;
  • классикалык __del__ катачылыктарынан (кайра тирилтүү, циклдердеги белгисиз иреттик, аяктоо) качуу;
  • tracemalloc, gc жана sys.getsizeof менен күтүлбөгөн эстек өсүшүн диагноздоо.

Бул тема сиз Python объект моделин — өткөн темадан идентификация, өзгөрүлмөлүүлүк жана көчүрүү семантикасын — мурунтан билесиз деп болжолдойт. Бул жерде биз бир деңгээл тереңге, ошол объекттерди тирүү кармаган аткаруу машинериясына түшөбүз.

1. Шилтемелерди эсептөө: негизги механизм

CPython түзгөн ар бир объект ob_refcnt деген кичине бүтүн сандык талааны алып жүрөт, ал ага азыр канча шилтеме көрсөтүп турганын эсептейт. Ат байлоо, тизмеге кошуу, аргумент өткөрүү — булардын ар бири эсептегичке бирди кошот; атты өчүрүү, аны кайра байлоо же көрүнүү аймагынан чыгуу бирди кемитет. Эреже так жана заматта: эсептегич нөлгө жеткен заматта объект бошотулат, анын __del__ (эгер бар болсо) иштейт жана өзүнүн шилтемелери бошотулат — бул каскад менен дагы көбүрөөк объектти бошото алат.

import sys

a = [10, 20, 30]     # тизме-объектте азыр бир шилтеме бар: 'a'
b = a                # ОШОЛ ЭЛЕ объектке экинчи шилтеме
print(sys.getrefcount(a))   # 3  (a, b жана getrefcount'тун өз аргументи)

del b                # бир шилтеме жоголду
print(sys.getrefcount(a))   # 2  (a жана аргумент)

del a                # акыркы чыныгы шилтеме жоголду -> эсептегич -> 0 -> азыр бошотулду

Ушул себептен CPython эстектин көбүн детерминдүү жана тез, «дүйнөнү токтотуу» тыныгуусуз бошотот: бошотуу кадимки шилтеме эсебине өрүлгөн. Ошондой эле контекст менеджери жапкан файл with блогу аяктап, анын акыркы шилтемеси жоголор замат дароо бошотулат.

Бул сабакты YourAIZone платформасында улантыңыз

Толук сабакта — толук түшүндүрмө, чыгарылган мисалдар, көп кездешкен каталар, заматта текшерилүүчү тесттер жана ЖИ-репетитор. Конок катары дароо баштаңыз же прогрессти сактоо үчүн аккаунт түзүңүз.

Толук сабакта

  • Толук түшүндүрмө
  • Чыгарылган мисалдар
  • Көп кездешкен каталар жана алардан кантип качуу керек
  • Тест суроолору: 15
  • Тема боюнча суроолорго жооп берген ЖИ-репетитор
  • Окуучу, ата-эне жана мугалим үчүн прогрессти көзөмөлдөө