Sobes.tech
Middle+

Ինչպես է աշխատում աղբամատը Go լեզվում?

sobes.tech AI

Պատասխան AI-ից

Go- ի աղբահանիչը իրականացնում է պառլելային, ոչ ճշգրիտ (non-generational) մեթոդ, հիմնված Mark-and-Sweep ալգորիթմի վրա, որի վրա ազդում է հզորության վրա հիմնված տրիգերը:

Աշխատանքի հիմնական սկզբունքները:

  1. Ակտիվացման տրիգեր: Աղբահանիչը սկսվում է, երբ տրամադրված հիշողության ծավալը գերազանցում է որոշակի շեմը: Այս շեմը դինամիկ կարգավորվում է:
  2. Նշման փուլ (Mark Phase):
    • Աղբահանիչը կանգնեցնում է միայն նշման փուլի կարևոր հատվածը (Stop-the-World, STW), բայց դա շատ կարճ ժամանակ է պահանջում:
    • Paralleլորեն աշխատող ծրագրի (mutator) հետ, աղբահանիչը շրջում է օբյեկտների գրաֆը, որը հիմնված է հիմնական ցուցիչների վրա (ռեգիստրներ, գլոբալ փոփոխականներ, գորուտինների ստեքներ):
    • Կենդանի (հասանելի) օբյեկտները նշվում են որպես օգտագործված:
  3. Մաքրման փուլ (Sweep Phase):
    • Նշման փուլը ավարտելուց հետո, աղբահանիչը անցնում է վարձակալված հիշողության ցանկը (spans):
    • Աննշան օբյեկտները համարվում են աղբ և նրանց հիշողությունը ազատվում է:
    • Այս փուլը նույնպես կատարվում է պառլելորեն ծրագրի աշխատանքի հետ:
  4. Write Barrier: Go- ն օգտագործում է write barrier՝ օբյեկտների գրաֆում փոփոխությունները հետևելու համար պառլելային նշման ժամանակ: Սա ապահովում է աղբահանիչի ճիշտ աշխատանքը, չնայած մուտատորից հիշողության փոփոխություններին:
  5. Ոչ սերունդներ: Բանաձևից տարբեր, Go- ն չի բաժանում օբյեկտները սերունդների, և աղբահանիչը ամբողջ հողը մշակում է ամբողջությամբ:
  6. Նվազագույն ուշացում: 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-ն դադարի հասանելի լինել (օրինակ՝ ֆունկցիայից դուրս գալու ժամանակ),
	// հավաքիչը ժամանակի ընթացքում ազատում է այն զբաղեցրած հիշողությունը:
}