Garbage Collection (GC): bu nədir, alqoritmlər və mobil inkişafda zibil yığımı

Müəllif: IT Sectr Dərc olunub: 2026-03-29 Oxuma vaxtı: 10 dəq

Zibil yığımı vasitəsilə avtomatik yaddaş idarəetməsi Android platformasının ART virtual maşınına əsaslanan əsas mexanizmidir. Google Android Documentation, 2026-ya gərə, zibil yığıcı tərtibatçını əl ilə yaddaş idarəetməsindən azad edir, artıq istinadı olmayan obyektləri avtomatik silir. GC olmadan hər bir obyekt ayrılması açıq şəkildə free və ya delete çağırılmasını tələb edərdi ki, bu da saniyədə milyonlarla obyekti olan Java ekosistemində fiziki cəhətdən mümkün deyil.

Əsas məqamlar

  • Garbage Collection — Java və Android-də istifadə olunmayan obyektləri silməklə yaddaşı avtomatik boşaltma mexanizmi
  • Əsas alqoritmlər — Mark-and-Sweep, Copying Collection və Generational Collection yığımın səmərəliliyini müyyənləşdirir
  • ART və Dalvik — Android virtual maşının iki tətbiqi, ART (Android Runtime) Android 5.0-dan başlayaraq Dalvik-i əvəz etdi
  • GC Pauses — yığım zamanı tətbiqin icrasının dayandırılması — jank və performans problemlərinin əsas səbəbi
  • GC Optimizasiyası — ayırmaların azaldılması, obyekt hovuzlarının istifadəsi və Collection tiplərinin düzgün seçilməsi yığıcının yükünü azaldır

Garbage Collection (GC) nədir?

Garbage Collection (GC) — proqram tərəfindən artıq istifadə edilməyən obyektlərin tutduğu yaddaşı aşkarlama və boşaltma avtomatik prosesidir. Mobil inkişaf kontekstində GC Android platformasında ART virtual maşını, həmçinin standart Java Virtual Machine vasitəsilə tətbiq olunur.

Əl ilə yaddaş idarəetməsi olan dillərdən (C, C++) fərqli olaraq, orada proqramçı açıq şəkildə free və ya delete çağırmalıdır, GC tamamilə obyektlərin həyat dövriyyəsini izləmə vəzifəsini üzərinə götürür. Tərtibatçı new operatoru vasitəsilə yeni obyektlər yaradır, yığıcı isə obyektin çatılmaz olduğu anı müyyənləşdirir — yəni ona heç bir aktiv istinad qalmayıb.

Əsas metrika GC-nin səmərəliliyi — pauza vaxtı (pause time) və ötürmə qabiliyyəti (throughput). Pauza — yığımın aparılması üçün tətbiqin icrasının dayandırıldığı müddətdir. Mobil mühitdə 8–16 millisaniyədən uzun pauzalar buraxılmış çərçivələr (jank) kimi nəzərə çarpır.

Google I/O 2019 məlumatlarına görə, Android 10-da ART tipik GC pauzalarını 2–4 ms-ə endirdi ki, bu da Android 4.4-dəki Dalvik ilə müqayisədə 70% azdır. Bununla belə, yaddaşla səhv işləmə — dövrülərdə obyektlərin tez-tez ayrılması, lazımsız müvəqqəti nüsxələrin yaradılması — performans problemlərinin əsas səbəbi olaraq qalır.

Zibil yığıcı necə işləyir: əsas alqoritmlər

Java və Android-də bütün GC tətbiqləri pauza vaxtı ilə təmizlik tamlığı arasında tarazlığa nail olmaq üçün birləşdirilən bir neçə fundamental alqoritmə əsaslanır. Bu alqoritmləri başa düşmək GC-friendly kod yazmaq üçün zəruridir.

Mark-and-Sweep

Mark-and-Sweep — iki mərhələdə işləyən ən sadə alqoritmdir. Mark mərhələsində yığıcı kök istinadlardan (root set) — yerli dəyişənlər, statik sahələr, iplik yığınları — başlayaraq obyekt qrafikini gəzir. Hər çatılan obyekt canlı bayrağı ilə qeyd olunur. Sweep mərhələsində yığıcı bütün yığını gəzir və qeyd olunmamış obyektlərin yaddaşını boşaldır.

Çatışmazlıq — yaddaş fraqmentasiyası: Sweep-dən sonra boş sahələr işğal olunmuş sahələrlə növbələşir ki, bu da böyük obyektlərin ayrılmasını çətinləşdirir. Mobil ssenarilərdə bu kritikdir, çünki yığın adətən kiçikdir (Android-də 64–512 MB).

Copying Collection

Copying Collection yığını iki yarım sahəyə (semi-spaces) bölür. Aktiv obyektlər bir yarım sahədən digərinə fasiləsiz şəkildə köçürülür. Köçürmədən sonra köhnə yarım sahə tamamilə boş elan edilir. Alqoritm fraqmentasiyanı tamamilə aradan qaldırır, lakin iki dəfə çox yaddaş tələb edir.

Mobil mühitlərdə Copying Collection nəsil yığıcıları tərəfindən statistik olaraq tez ölən gənc obyektlərin sürətli təmizlənməsi üçün istifadə olunur (zəif nəsil hipotezi).

Generational Collection

Generational Collection yığını nəsillərə bölür: Young Generation (gənc obyektlər) və Old Generation (bir neçə yığımdan sağ çıxmış köhnələr). Gənc nəsilin yığımı (Minor GC) tez və sürətli aparılır, çünki əksər obyektlər gənc ikən ölür. Köhnə nəsilin yığımı (Major GC və ya Full GC) daha az baş verir, lakin daha uzun çəkir.

java
// Nəsilli GC-nin nümayisi: gənc obyektlər tez ölür
void processItems(List<Item> items) {
    List<Result> results = new ArrayList<>();       // bütün metod boyu yaşayır
    for (Item item : items) {
        Result r = new Result(item.getValue());    // dərhal ölür
        if (r.isValid()) {
            process(r);                               // r zibilə çevrilir
        }
    }
    saveResults(results);                             // results Old Gen-ə keçir
}

Bu nümunədə Result obyektləri dövrənin içində yaradılır və dərhal zibilə çevrilir — onlar Young GC üçün ideal namizədlərdir. results obyekti daha uzun yaşayır və Old Generation-a keçir. Nəsillərə bölgü Minor GC-yə köhnə yığına toxunmadan gənc obyektləri millisaniyələrdə təmizləməyə imkan verir.

Android-də Garbage Collection: ART və Dalvik

Android Dalvik VM-dən ART (Android Runtime)-a qədər yol keçdi və GC tətbiqi onlar arasındakı əsas fərqlərdən biridir. Android-də GC arxitekturasını başa düşmək real cihazlarda pauzaları minimuma endirən kod yazmağa kömək edir.

XarakteristikasıDalvik (4.4-dək)ART (5.0+)
GC növüConcurrent Mark ilə Mark-and-SweepNəsilli + Concurrent
Tipik pauza10–30 ms2–4 ms
KompaktlaşdırmaXeyr (yalnız fraqmentasiya artır)Bəli (fon rejimində, tətbiqi dayandırmadan)
AOT-kompilyasiyaJIT (Just-In-Time)AOT + JIT (hibrid)

Dalvik GC

Dalvik concurrent fazası ilə Mark-and-Sweep kombinasiyasından istifadə edirdi. Concurrent Mark tətbiqə obyekt qrafikini gəzmə zamanı işləməyə davam etməyə imkan verirdi, lakin Sweep mərhələsi bütün ipliklərin dayandırılmasını (Stop-The-World) tələb edirdi. Az miqdarda RAM (512 MB — 1 GB) olan cihazlarda pauzalar 30 ms-ə çatırdı ki, bu da interfeysdə nəzərə çarpan ləngimələrə səbəb olurdu. Bundan əlavə, Dalvik yığını kompaktlaşdırmırdı, buna görə də uzun müddətli işdən sonra fraqmentasiya artır və böyük obyektlərin (məsələn, Bitmap) ayrılması kifayət qədər ümumi boş yaddaş olsa belə OutOfMemoryError verə bilərdi.

ART GC

ART (Android Runtime) concurrent kompaktlaşdırma ilə nəsilli yığıcı tətbiq etdi. Yığın üç regiona bölünür: Young, Mature (Old Generation analoqu) və Large Object Space (12 KB-dan böyük obyektlər üçün). Young Region yığımı əksər hallarda iplikləri dayandırmadan paralel şəkildə aparılır. Android 10+-da Concurrent Copying meydana çıxdı — kompaktlaşdırma Stop-The-World olmadan fon iplikdə aparılır.

ART arxitekturası sayəsində tipik GC pauzaları 2–4 ms-ə endi, gənc obyektlərin üstünlük təşkil etdiyi ssenarilərdə isə 0.5–1 ms-ə qədər azaldı. Bu, Android cihazlarına aktiv yaddaş işində belə stabill 60 FPS təmin etməyə imkan verdi.

Java-da zibil yığıcının növləri

Java ekosistemində hər biri öz performans profilinə malik bir neçə GC tətbiqi var. Android inkişafı üçün seçim ART ilə məhduddur, lakin Java GC haqqında bilik mobil tətbiqlərin server hissəsini yazarkən və Kotlin Multiplatform-da inkişaf edərkən faydalıdır.

Serial GC

Serial GC — tətbiqin tam dayandırılması ilə (Stop-The-World) tək iplikli yığıcı. Hər bir Mark, Sweep və Compact əməliyyatı bir iplik tərəfindən yerinə yetirilir. Performans aşağıdır — mobil serverlər üçün tətbiq edilmir. Yalnız 100 MB-dək yığını olan kiçik tətbiqlər üçün uyğundur.

Parallel GC

Parallel GC (həmçinin Throughput Collector kimi tanınır) bütün yığım mərhələləri üçün bir neçə iplik istifadə edir. Maksimum ötürmə qabiliyyətinə (throughput) yönəlib — GC-yə sərf olunan vaxtı tətbiqin iş vaxtına nisbətdə minimuma endirir. JVM-də -XX:+UseParallelGC bayrağı vasitəsilə aktivləşdirilir.

G1 GC

G1 (Garbage-First) GC — Java 9+-da defolt yığıcı. Yığın 1–32 MB-lıq regionlara bölünür. G1 pauza vaxtını proqnozlaşdırır və verilmiş limitə (defolt 200 ms) sığmağa çalışır. Prioritet: ən çox zibil olan regionlar əvvəlcə təmizlənir (adı da buradan gəlir). G1 böyük yığınlı serverlər (4–64 GB) və proqnozlaşdırıla bilən pauzalar üçün səmərəlidir.

java
// Hədəf pauzası 100 ms olan G1 GC-nin aktivləşdirilməsi
// java -XX:+UseG1GC -XX:MaxGCPauseMillis=100 -jar app.jar

public class MemoryMonitor {
    private static final long THRESHOLD = 512 * 1024 * 1024; // 512 MB

    public void checkHeapUsage() {
        Runtime rt = Runtime.getRuntime();
        long used = rt.totalMemory() - rt.freeMemory();
        if (used > THRESHOLD) {
            System.out.println("Yığın istifadə həddi aşıldı: " + used);
            System.out.println("Ayırmaları azaltmağı düşünün");
        }
    }
}

Runtime vasitəsilə yığının monitorinqi erkən mərhələdə yaddaş sızıntılarını aşkarlamağa imkan verir. Stabil işdə used maksimal yığının 80%-dən çox olarsa — bu, mümkün yaddaş sızıntısı və ya tətbiq tərəfindən həddən artıq yaddaş istehlakı siqnalıdır.

GC problemləri və mobil tətbiqlərdə yaddaş optimizasiyası

Hətta müasir ART GC bütün problemləri həll etmir — yaddaşın düzgün istifadə edilməməsi jank və ANR-nin (Application Not Responding) əsas səbəbi olaraq qalır. Əsas ssenariləri və optimizasiya metodlarını nəzərdən keçirək.

GC Pauses və Jank

GC Pauses — yığım zamanı tətbiq ipliklərinin dayandırılması. Ekranda bu, iki çərçivə arasındakı vaxt 16.6 ms-dən (60 FPS) çox olduqda buraxılmış çərçivələr kimi özünü göstərir. GC 30 ms çəkərsə, iki çərçivə əvəzinə yalnız biri çəkilir — istifadəçi interfeysdə ləngimə görür.

Uzun pauzaların əsas səbəbləri: Old Generation-da çox sayda canlı obyekt, yığın fraqmentasiyası, tez-tez Full GC. Diaqnostika üçün Android Studio Profiler və systrace istifadə olunur.

GC yükünün azaldılması

Əsas qayda GC-friendly kod — ayrılan obyektlərin sayını minimuma endirmək. Hər yeni obyekt təkcə yaddaşın ayrılmasını deyil, həm də sonradan yığımı tələb edir. GC sürətli olsa belə, saniyədə 1000 lazımsız ayırma yığıcıya 1000 yoxlama verir.

  • Dövrülərdə obyekt yaratmaqdan çəkinin — yaratmanı dövrədən kənara çıxarın, yerli dəyişənləri təkrar istifadə edin
  • Obyekt hovuzlarından istifadə edin — Bitmap, byte[] və digər ağır strukturlar üçün Object Pool və ya RecyclerView.ViewHolder tətbiq edin
  • Primitivlərə üstünlük verin — Integer əvəzinə int, Float əvəzinə float avtomatik qablaşdırmadan (autoboxing) qaçınır
  • SparseArray istifadə edin — Android SDK-da HashMap<Integer, V> əvəzinə primitivlərlə işləyən SparseArray, LongSparseArray var
  • Konkatenasiya əvəzinə StringBuilder — hər sətr əlavəsi yeni bir String obyekti yaradır

Yaddaş sızıntıları

Yaddaş sızıntısı obyekt çatılan olaraq qaldıqda baş verir, baxmayaraq ki, artıq lazım deyil. GC belə bir obyekti silə bilməz və yaddaş tədricən tükənir. Tipik səbəblər: qeydiyyatdan çıxarılmamış dinləyicilər, Activity-yə statik istinadlar, xarici konteksti tutan anonim siniflər və bağlanmamış Cursor/InputStream.

java
// Yaddaş sızıntısı: anonim sinif Activity-yə istinad saxlayır
public void startTask() {
    new Thread(new Runnable() {                    // gizli şəkildə this (Activity) saxlayır
        @Override
        public void run() {
            // uzun əməliyyat...
            System.out.println("Hazır");
        }
    }).start();
}

// Düzəliş: statik iç içə sinif + WeakReference
private static class TaskRunnable implements Runnable {
    private WeakReference<Activity> activityRef;

    TaskRunnable(Activity activity) {
        this.activityRef = new WeakReference<>(activity);
    }

    @Override
    public void run() {
        Activity act = activityRef.get();
        if (act != null) {
            // Activity ilə təhlükəsiz iş
        }
    }
}

Bu nümunədə anonim Runnable Activity-yə gizli istinad tutur. İplik canlı olduğu müddətçə — istifadəçi ekranı bağlasa belə, Activity GC tərəfindən yığıla bilməz. WeakReference + static class düzəlişi bu zənciri qırır və Activity-nin utilizasiyasına imkan verir.

Tez-tez verilən suallar

Android-də GC Java-dakı GC-dən nə ilə fərqlənir?

Android-də GC (ART) — məhdud yaddaşlı mobil cihazlar üçün optimallaşdırılmış, concurrent kompaktlaşdırma ilə nəsilli yığıcıdır. Java GC (G1, ZGC) — böyük yığınlar və proqnozlaşdırıla bilən pauzalarla server yığıcılarıdır. ART GC JVM bayraqlarından istifadə etmir — bütün konfiqurasiya əməliyyat sistemi səviyyəsində avtomatik aparılır.

GC-də Stop-The-World nədir?

Stop-The-World — yığıcının obyekt qrafikində təhlükəsiz gəzmək və ya yaddaşı boşaltmaq üçün tətbiqin bütün ipliklərini dayandırdığı andır. STW nə qədər uzun olsa, jank bir o qədər nəzərə çarpardı. ART nəsilli arxitektura sayəsində tipik STW vaxtını 2–4 ms-ə endirdi.

Android-də yaddaş sızıntısını necə aşkarlamaq olar?

Android Studio Memory Profiler istifadə edin — yığının artımını, ayırmaların sayını göstərir və Heap Dump etməyə imkan verir. Dərin təhlil üçün LeakCanary tətbiq edin — kitabxana avtomatik olaraq sızıntıları aşkarlayır və GC yığımına mane olan istinad zəncirini göstərir.

Full GC nə vaxt baş verir və niyə təhlükəlidir?

Full GC — Old Generation daxil olmaqla bütün nəsil yığınlarının tam yığımıdır. Mobil tətbiqlərdə Full GC 50–200 ms çəkə bilər, nəzərə çarpan jank və ya ANR səbəb olur. Əsas səbəblər: yığın fraqmentasiyası, yaddaş sızıntıları, Old Generation həddinin aşılması.

Kotlin yaddaş sızıntılarından qaçmağa necə kömək edir?

Kotlin strukturlaşdırılmış konkurentlik ilə korutinlər təmin edir — scope ləğv edilməsi avtomatik olaraq bütün uşaq korutinləri ləğv edir, sızıntıların qarşısını alır. Həmçinin Kotlin-də tənbəl inisializasiya üçün lazy delegatı və müvəqqəti obyektlərin sayını azaldan görünmə şərh əməliyyatları var.

Nəticələr

  • Garbage Collection — çatılmayan obyektlərin silinməsi ilə avtomatik yaddaş idarəetməsi, Android Runtime-ın əsası
  • Mark-and-Sweep — iki fazalı yığım ilə əsas alqoritm, yığın fraqmentasiyasından əziyyət çəkir
  • Copying Collection — canlı obyektləri yığıcam yarım sahəyə köçürməklə fraqmentasiyanı aradan qaldırır
  • Generational GC — yığını nəsillərə (Young/Old) bölür, gənc qısaömürlü obyektlərin yığımını sürətləndirir
  • Android-də ART — Android 5.0-da Dalvik-i əvəz edən, concurrent kompaktlaşdırma və 2–4 ms pauzalarla nəsilli yığıcı
  • GC optimizasiyası — ayırmaların azaldılması, obyekt hovuzları, qablaşdırıcılar əvəzinə primitivlər və HashMap əvəzinə SparseArray yığıcının yükünü azaldır
  • Diaqnostika — Android Studio Profiler, systrace və LeakCanary yaddaş problemlərini aşkarlamaq üçün əsas alətlərdir

Açar təslim mobil tətbiq hazırlayacağıq

IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.

Layihəni müzakirə et

Həm də oxuyun