Middle+
Ինչպես է աշխատում աղբամատը Go լեզվում?
sobes.tech AI
Պատասխան AI-ից
Go- ի աղբահանիչը իրականացնում է պառլելային, ոչ ճշգրիտ (non-generational) մեթոդ, հիմնված Mark-and-Sweep ալգորիթմի վրա, որի վրա ազդում է հզորության վրա հիմնված տրիգերը:
Աշխատանքի հիմնական սկզբունքները:
- Ակտիվացման տրիգեր: Աղբահանիչը սկսվում է, երբ տրամադրված հիշողության ծավալը գերազանցում է որոշակի շեմը: Այս շեմը դինամիկ կարգավորվում է:
- Նշման փուլ (Mark Phase):
- Աղբահանիչը կանգնեցնում է միայն նշման փուլի կարևոր հատվածը (Stop-the-World, STW), բայց դա շատ կարճ ժամանակ է պահանջում:
- Paralleլորեն աշխատող ծրագրի (mutator) հետ, աղբահանիչը շրջում է օբյեկտների գրաֆը, որը հիմնված է հիմնական ցուցիչների վրա (ռեգիստրներ, գլոբալ փոփոխականներ, գորուտինների ստեքներ):
- Կենդանի (հասանելի) օբյեկտները նշվում են որպես օգտագործված:
- Մաքրման փուլ (Sweep Phase):
- Նշման փուլը ավարտելուց հետո, աղբահանիչը անցնում է վարձակալված հիշողության ցանկը (spans):
- Աննշան օբյեկտները համարվում են աղբ և նրանց հիշողությունը ազատվում է:
- Այս փուլը նույնպես կատարվում է պառլելորեն ծրագրի աշխատանքի հետ:
- Write Barrier: Go- ն օգտագործում է write barrier՝ օբյեկտների գրաֆում փոփոխությունները հետևելու համար պառլելային նշման ժամանակ: Սա ապահովում է աղբահանիչի ճիշտ աշխատանքը, չնայած մուտատորից հիշողության փոփոխություններին:
- Ոչ սերունդներ: Բանաձևից տարբեր, Go- ն չի բաժանում օբյեկտները սերունդների, և աղբահանիչը ամբողջ հողը մշակում է ամբողջությամբ:
- Նվազագույն ուշացում: Go GC-ի նախագծման ժամանակ նպատակ էր դրել նվազեցնել սպասումները, որոնք առաջանում են աղբի հավաքման ժամանակ (STW ընդմիջումներ), ինչը այն դարձնում է սերվերային ծրագրերի համար հարմար:
Պառլելային և write barrier- ի օգտագործումը թույլ է տալիս աղբահանիչին նվազեցնել ծրագրի կանգառի ժամանակը՝ ապահովելով բարձր արտադրողականություն:
Օրինակ՝ հիշողության պարզեցված կառավարում (ուղղակի GC չէ, բայց ցույց է տալիս ռեսուրսների ազատում):
package main
import (
"fmt"
"os"
)
func main() {
// Օրինակ՝ ժամանակավոր ռեսուրս ստեղծել, որը կազատվի
file, err := os.Create("temp.txt")
if err != nil {
fmt.Println("Սխալ ֆայլ ստեղծելիս:", err)
return
}
// Ֆայլի հետագա փակումը:
// Չնայած սա ուղղակի GC չէ, այն ցույց է տալիս ռեսուրսների ազատումը:
defer file.Close()
fmt.Println("Ֆայլ 'temp.txt' ստեղծվեց:")
// Հետագայում ծրագրը կարող է աշխատել ֆայլի հետ...
// GC- ն ավտոմատ կերպով աշխատում է ֆոնային ռեժիմում՝ անօգտագործվող օբյեկտները հավաքելու համար:
// Օրինակ, եթե ստեղծենք սլայս կամ մապ:
data := make([]int, 1000000) // Հատկացում հողում
_ = data // Օգտագործում
// Երբ data-ն դադարի հասանելի լինել (օրինակ՝ ֆունկցիայից դուրս գալու ժամանակ),
// հավաքիչը ժամանակի ընթացքում ազատում է այն զբաղեցրած հիշողությունը:
}