
Санах ойн автомат болон гар удирдлагын ялгаа

У.Санж-Очир
Багш


У.Санж-Очир
Багш
Програм ажиллаж байх үед өгөгдөл бүр тодорхой хэмжээний санах ой (Memory) ашигладаг. Хувьсагч үүсгэх, объект байгуулах, файл боловсруулах, хэрэглэгчийн мэдээлэл хадгалах зэрэг бүхий л үйлдэл санах ойтой шууд холбоотой.
Гэхдээ програм ашиглахаа больсон өгөгдлийн санах ойг хэн чөлөөлөх ёстой вэ?
Энэ асуултад програмчлалын ертөнц хоёр үндсэн арга барилаар хариулдаг. Нэг нь Garbage Collection (GC) буюу ашиглагдахгүй болсон санах ойг автоматаар цэвэрлэх механизм. Нөгөө нь Manual Memory Management буюу программист санах ойн ашиглалт, чөлөөлөлтийг өөрөө хариуцан удирдах арга юм.
Эдгээр нь програмын гүйцэтгэл, найдвартай байдал, хөгжүүлэлтийн хурд болон системийн нөөцийн зарцуулалтад чухал нөлөө үзүүлдэг.
Memory Management буюу санах ойн удирдлага гэдэг нь програм ажиллах хугацаандаа санах ойг хэрхэн хуваарилах (Allocation), ашиглах (Usage), чөлөөлөх (Deallocation) үйл явцыг зохицуулахыг хэлнэ.
Жишээлбэл, хэрэглэгч нэг сая ширхэг тоо агуулсан массив үүсгэлээ гэж бодъё. Тухайн массивыг хадгалахын тулд компьютерийн RAM-аас тодорхой хэмжээний зай шаардлагатай болно.
Харин массив хэрэггүй болсон үед түүний эзэлж байсан санах ойг дахин ашиглах боломжтой болгох ёстой.

Хэрэв санах ойг зөв удирдахгүй бол дараах асуудлууд үүсэж болно.
Memory Leak: Ашиглагдахгүй болсон санах ой буцаан чөлөөлөгдөхгүй үлдэх.
Dangling Pointer: Чөлөөлөгдсөн санах ойн хаягийг заасан заагч үлдэх.
Out of Memory: Програмд шаардлагатай санах ой хүрэлцэхгүй болох.
Performance Degradation: Санах ойн зохисгүй ашиглалтаас програмын гүйцэтгэл буурах.
Эдгээр асуудлыг бууруулахын тулд програмчлалын хэлүүд санах ойг удирдах өөр өөр шийдэл ашигладаг.
Garbage Collection (GC) гэдэг нь програмд цаашид ашиглах боломжгүй болсон объектуудын эзэлж буй санах ойг автоматаар илрүүлж, чөлөөлөх механизм юм.
Энэ аргыг Java, C#, Go, JavaScript, Python зэрэг олон хэл ашигладаг. Гэхдээ Python-ийн хувьд reference counting болон циклийн garbage collector хослон ажилладаг тул бүх хэл яг ижил механизмтай гэсэн үг биш.
GC ашигладаг орчинд программист объект үүсгэхдээ санах ойг гараар чөлөөлөх талаар ихэвчлэн санаа зовох шаардлагагүй.
Түгээмэл хэрэглэгддэг GC алгоритмуудын нэг нь Mark-and-Sweep юм. Энэ нь хоёр үндсэн үе шаттай.
Mark: Програмын ашиглаж болох эхлэл цэгүүдээс хүрч болох объектуудыг тэмдэглэнэ.
Sweep: Тэмдэглэгдээгүй, хүрэх боломжгүй объектуудын санах ойг чөлөөлнө.
Garbage Collection-ийн давуу болон сул талууд
Давуу тал:
Программистын гараар санах ой чөлөөлөх ажлыг багасгана.
Use-after-free болон double-free төрлийн алдаа гарах эрсдэлийг бууруулна.
Хөгжүүлэлтийг хялбарчилж, кодын засвар үйлчилгээг сайжруулна.
Том хэмжээний application хөгжүүлэхэд бүтээмж нэмэгдүүлдэг.
Сул тал:
GC ажиллах үед нэмэлт CPU нөөц ашиглана.
Зарим GC нь програмын ажиллагаанд түр завсарлага (GC Pause) үүсгэдэг.
Санах ойг хэзээ чөлөөлөхийг программист бүрэн хянах боломж хязгаарлагдмал.
Зарим workload-д илүү их санах ой шаардаж болно.
Орчин үеийн concurrent болон low-pause GC-ууд эдгээр сул талуудыг бууруулж чаддаг ч бүх нөхцөлд бүрэн арилгадаггүй.
Manual Memory Management гэдэг нь программист шаардлагатай санах ойг өөрөө хуваарилж, хэрэггүй болсон үед чөлөөлөхийг хариуцдаг арга юм.
C болон C++ зэрэг хэлүүдэд энэ арга түгээмэл хэрэглэгддэг.
Тухайлбал, C хэлэнд malloc() ашиглан динамик санах ой хуваарилж, free() ашиглан чөлөөлдөг.
Давуу тал:
Санах ойн хуваарилалт, чөлөөлөлтийг нарийн хянах боломжтой.
GC-ийн автомат цэвэрлэгээний түр завсарлага байхгүй.
Embedded system, operating system, game engine зэрэг системийн түвшний програмчлалд тохиромжтой.
Зөв зохион байгуулбал санах ойн ашиглалтыг маш үр ашигтай болгож чадна.
Сул тал:
Memory Leak, Dangling Pointer, Double Free зэрэг алдааны эрсдэл өндөр.
Хөгжүүлэлт болон debugging илүү төвөгтэй.
Программистаас санах ойн lifecycle-ийн нарийн ойлголт шаарддаг.
Буруу хандалт нь програм гацах, өгөгдөл гэмтэх, аюулгүй байдлын эмзэг байдал үүсгэх боломжтой.

Garbage Collection болон Manual Memory Management нь нэг асуудлыг өөр өөр арга замаар шийддэг хоёр үндсэн хандлага юм.
Garbage Collection нь санах ойг автоматаар удирдсанаар хөгжүүлэлтийг хялбарчилж, санах ойн зарим төрлийн алдаанаас хамгаалдаг. Харин Manual Memory Management нь программистад илүү шууд хяналт өгдөг ч илүү их хариуцлага шаарддаг.
Rust-ийн Ownership, C++-ийн RAII зэрэг арга барилууд эдгээр хоёрын заагийг улам өргөжүүлж байна.
Эцсийн эцэст хамгийн сайн Memory Management арга нь ганцхан байдаггүй. Тухайн системийн шаардлага, гүйцэтгэлийн зорилго, нөөцийн хязгаарлалт, хөгжүүлэлтийн багийн туршлагаас шалтгаалан зөв сонголт өөрчлөгдөнө.
Сайн программист санах ойг зөвхөн ашиглаж чаддаг биш, түүний lifecycle-ийг ойлгож, шаардлагатай үед оновчтой удирдаж чаддаг байх ёстой.