---
title: 'Anlık Görüntü Kalıcılığı'
source: 'https://academia.sh/tr/kurslar/bellek-ici-depolar/anlik-goruntu-kaliciligi'
course: 'Bellek İçi Depolar ve Önbellek Sistemleri'
language: tr
updated: '2026-08-17T18:08:58+00:00'
license: 'CC BY-SA 4.0'
---

# Anlık Görüntü Kalıcılığı

Deponun bütününü aralıklarla diske yazan kalıcılık biçimi: aralığın kayıp penceresindeki yazma sayısına etkisi, üç aralığın disk maliyeti, bellekte tutulan bayt ile görüntü dosyasının boyutu arasındaki fark ve görüntü alırken duraklatmak ile kopyalamak arasındaki seçim.

Önceki konu ödünç sistemini bütünüyle bellekte kurdu: katalog girişleri, oturum kayıtları,
ödünç sayaçları, bekleme listeleri, sıralama tabloları. Her yapı için tutulan bayt sayıldı ve
karşılığında ne satın alındığı ölçüldü. Bütün o ölçümlerin ortak ve sessiz bir varsayımı
vardı: süreç çalışıyor. Süreç durduğunda geriye hiçbiri kalmaz. Dayanıklılığın bir ayar
olduğu söylendi; o ayarın ne yaptığı, neye mal olduğu ve kapalıyken tam olarak neyin yittiği
sorulmadı.

Bu ders ayarın ilk biçimini ele alır: belirli aralıklarla deponun **bütününü** diske yazmak.
İki sorusu vardır. Süreç durduğunda kaç yazma yiter, ve görüntüyü almanın kendisi çalışmaya
devam eden depoya ne kadara mal olur? İkisi de aynı düğmeye — aralığa — bağlıdır ve ters
yönlere çeker.

## Deponun ve Ölçünün Kurulumu

Ölçüm için ödünç deposu doğrudan yazılır. Depo bir anahtar–değer eşlemesidir; her yazmada
tuttuğu bayt sayısını da günceller, böylece bellek maliyeti tahmin edilmez, sayılır.

**KB1.** Bir girişin bellek maliyeti anahtarın baytı, değerin baytı ve giriş başına sabit
48 bayt üstveridir. Bu 48 bayt karma tablo yuvasını, iki uzunluk alanını ve giriş
işaretçisini temsil eder; gerçek bir çalışma zamanında sayı biraz oynar, ölçümün yönü
oynamaz.

```js
// depo.mjs — bellek içi ödünç deposu ve anlık görüntü alıcısı
export const USTVERI = 48;          // KB1: giriş başına sabit üstveri (yuva + işaretçi + uzunluk)

export class Depo {
  constructor() { this.girisler = new Map(); this.bayt = 0; }
  #maliyet(a, d) { return Buffer.byteLength(a) + Buffer.byteLength(d) + USTVERI; }
  yaz(a, d) {
    const eski = this.girisler.get(a);
    if (eski !== undefined) this.bayt -= this.#maliyet(a, eski);
    this.girisler.set(a, d);
    this.bayt += this.#maliyet(a, d);
  }
  get sayi() { return this.girisler.size; }
  goruntule() {                     // anlık görüntü: bütün girişler tek geçişte diziye çevrilir
    let s = '';
    for (const [a, d] of this.girisler) s += a + '\t' + d + '\n';
    return s;
  }
}

export function uretec(tohum) {     // belirlenimci sözde rastgele üreteç
  let a = tohum >>> 0;
  return () => {
    a = (a + 0x6d2b79f5) >>> 0;
    let t = a;
    t = Math.imul(t ^ (t >>> 15), t | 1);
    t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
    return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
  };
}

export function yukUret(sayi, tohum, uyeSayisi = 20000) {
  const r = uretec(tohum), liste = [];
  for (let i = 0; i < sayi; i++) {
    const u = Math.floor(r() * uyeSayisi);
    liste.push([
      'odunc:u' + String(u).padStart(5, '0'),
      `sube=${1 + (u % 8)};gun=${[7, 14, 28][i % 3]};yenileme=${i % 4}`,
    ]);
  }
  return liste;
}
```

Yük, kütüphanenin ödünç trafiğidir: yirmi bin üyeye dağılan altmış bin ödünç yazması. Üreteç
kendi yazılmıştır ve tohumu görünürdür, dolayısıyla aşağıdaki sayıların hepsi yeniden
üretilebilir.

## Aralık, Kayıp Penceresi ve Disk

Anlık görüntü kalıcılığında dayanıklılık tek bir düğmeyle ayarlanır: kaç yazmada bir görüntü
alınacağı. Aşağıdaki koşum aynı altmış bin yazmayı üç aralıkla oynatır. Her yazmadan sonra "o
anda süreç dursaydı kaç yazma yiterdi" sorusunun yanıtı biriktirilir; sonda ortalaması ve en
kötüsü basılır.

```js
// aralik.mjs — üç anlık görüntü aralığının kayıp penceresi ve disk maliyeti
import { writeFileSync, statSync } from 'node:fs';
import { Depo, yukUret } from './depo.mjs';

const YUK = yukUret(60000, 20260731);
console.log('yük: 60000 yazma, 20000 üye, tohum 20260731');
console.log('aralık  görüntü  diske(MB)  ortalama kayıp  en kötü kayıp');

for (const aralik of [1000, 5000, 20000]) {
  const depo = new Depo();
  let goruntu = 0, diskBayt = 0, kayipToplam = 0, enKotu = 0, sonGoruntu = 0;
  for (let i = 0; i < YUK.length; i++) {
    depo.yaz(YUK[i][0], YUK[i][1]);
    const kayip = (i + 1) - sonGoruntu;        // süreç bu anda dursa yitecek yazma sayısı
    kayipToplam += kayip;
    if (kayip > enKotu) enKotu = kayip;
    if ((i + 1) % aralik === 0) {
      diskBayt += Buffer.byteLength(depo.goruntule());
      goruntu++;
      sonGoruntu = i + 1;
    }
  }
  console.log(String(aralik).padStart(6), String(goruntu).padStart(8),
    String(Math.round(diskBayt / 1048576)).padStart(10),
    String(Math.round(kayipToplam / YUK.length)).padStart(15), String(enKotu).padStart(14));
}

const son = new Depo();
for (const [a, d] of YUK) son.yaz(a, d);
writeFileSync('goruntu.txt', son.goruntule());
console.log('depo:', son.sayi, 'giriş,', son.bayt, 'bayt bellekte |',
  'görüntü dosyası', statSync('goruntu.txt').size, 'bayt');
```

```
yük: 60000 yazma, 20000 üye, tohum 20260731
aralık  görüntü  diske(MB)  ortalama kayıp  en kötü kayıp
  1000       60         30             501           1000
  5000       12          6            2501           5000
 20000        3          2           10001          20000
depo: 19040 giriş, 1593100 bayt bellekte | görüntü dosyası 717260 bayt
```

Kayıp penceresi aralığın doğrudan işlevidir: ortalaması aralığın yarısı, en kötüsü aralığın
kendisidir. Bin yazmalık aralık, yirmi binliğe göre ortalama 9.500 yazmayı kurtarır. Bu satın
alınan şeydir ve bedeli aynı satırda yazılıdır: 2 MB yerine 30 MB disk yazımı, yani on beş
kat. Bedelin böyle büyümesinin nedeni, anlık görüntünün **her seferinde deponun tamamını**
yazmasıdır. Bin yazmalık bir değişiklik için de yaklaşık beş yüz kilobaytlık bütün depo
yeniden diske gider.

Son satır ikinci bir ayrımı verir. Altmış bin yazmadan geriye 19.040 giriş kalmıştır; geri
kalanı aynı üyelerin kayıtlarının üzerine yazmıştır. Anlık görüntünün boyutu yazma sayısıyla
değil **anahtar sayısıyla** büyür — bu, sonraki dersteki günlük biçimiyle arasındaki temel
farktır. Aynı veri bellekte 1.593.100 bayt, dosyada 717.260 bayt tutar: dosya, belleğin
yarısından azıdır. Fark üstveridir. Karma tablo yuvaları, işaretçiler ve uzunluk alanları
diske gitmez. Diskteki dosyanın küçüklüğüne bakıp deponun belleğe rahat sığacağı sonucunu
çıkarmak, giriş başına iki katlık bir hatayı baştan kabul etmek olur.

## Görüntü Almanın Kendi Maliyeti

Görüntünün tutarlı olması gerekir: yarısı eski, yarısı yeni bir dosyadan kurtarma yapılamaz.
Tutarlılığı sağlamanın iki yolu vardır ve ikisi de bedava değildir.

**Duraklatmak.** Görüntü alınırken yazmalar bekletilir. Bellek maliyeti sıfırdır, bedelini
istemciler bekleme süresiyle öder.

**Kopyalamak.** Yazmalar sürer; görüntüye girecek bir giriş değiştirilmek üzereyken eski hâli
kopyalanır ve görüntü kopyayı okur. Kimse beklemez, bedelini bellek öder: görüntü bitene
kadar kopyalar da tutulur.

**KB2.** Görüntü alma anlık değildir; taranan her bin giriş kırk yazmalık süre alır. Süre,
koşum ortamına değil giriş sayısına bağlı bir birimle sayılır.

```js
// kopya.mjs — görüntü alma sırasındaki iki seçenek: duraklatmak ya da kopyalamak
import { Depo, USTVERI, yukUret } from './depo.mjs';

const YUK = yukUret(60000, 20260731);
const TARAMA = 40;                    // KB2: her 1.000 giriş için 40 yazmalık tarama süresi
console.log('aralık  görüntü  tarama  duraklatan: bekleyen  kopyalayan: giriş  tepe bayt');

for (const aralik of [1000, 5000, 20000]) {
  const depo = new Depo();
  let goruntu = 0, sure = 0, bekleyen = 0, kopyaSayi = 0, tepe = 0, kalan = 0, kopya = null;
  for (let i = 0; i < YUK.length; i++) {
    const [a, d] = YUK[i];
    if (kalan > 0) {                  // görüntü alınıyor: değişen giriş önce kopyalanır
      const eski = depo.girisler.get(a);
      if (eski !== undefined && !kopya.has(a)) { kopya.set(a, eski); kopyaSayi++; }
      if (--kalan === 0) {
        let b = 0;
        for (const [k, v] of kopya) b += Buffer.byteLength(k) + Buffer.byteLength(v) + USTVERI;
        if (b > tepe) tepe = b;
        kopya = null;
      }
    }
    depo.yaz(a, d);
    if ((i + 1) % aralik === 0) {
      sure = Math.ceil((depo.sayi / 1000) * TARAMA);
      goruntu++; bekleyen += sure; kalan = sure; kopya = new Map();
    }
  }
  console.log(String(aralik).padStart(6), String(goruntu).padStart(8), String(sure).padStart(7),
    String(bekleyen).padStart(21), String(kopyaSayi).padStart(18), String(tepe).padStart(10));
}
```

```
aralık  görüntü  tarama  duraklatan: bekleyen  kopyalayan: giriş  tepe bayt
  1000       60     762                 33285              24985      59565
  5000       12     762                  6946               4710      58498
 20000        3     762                  1965                913      49266
```

Tarama süresi üç satırda da aynıdır: 762 yazma. Görüntü alma aralığa değil giriş sayısına
bağlıdır, dolayısıyla aralığı kısaltmak taramayı hızlandırmaz, yalnız daha sık yapar.

Duraklatan seçenek bin yazmalık aralıkta altmış bin yazmanın 33.285'ini bekletir — yükün
yarısından fazlası. Yirmi binlik aralıkta bu sayı 1.965'e iner. Kopyalayan seçenek hiçbir
yazmayı bekletmez; karşılığında görüntü sürerken en çok 59.565 bayt fazladan tutar. Bu,
deponun 1.593.100 baytının yaklaşık yüzde 3,7'sidir. Tepe değerin üç aralıkta da birbirine
yakın çıkması aynı nedendendir: tepeyi belirleyen aralık değil, tarama süresi boyunca kaç
**ayrı** anahtara dokunulduğudur. 762 yazma en fazla 762 ayrı giriş kopyalatabilirdi; tekrar
eden üyeler yüzünden sayı görüntü başına dört yüz civarında kalır. Yazmalar birkaç sıcak
anahtara yığılsaydı kopya daha da azalırdı; her yazma ayrı bir anahtara gitseydi tepe iki
katına yaklaşırdı.

Toplam kopyalanan giriş sayısı ise aralıkla birlikte artar: 24.985 karşısında 913. Kopyalama
tepe bellekte ucuzdur, ama görüntü sıklaştıkça yapılan iş olarak birikir.

Bin yazmalık aralıkta gizli bir sınır da görünür hâle gelir. Tarama 762 yazma sürüyorsa, depo
bin yazmanın 762'sinde görüntü alıyor demektir. Aralık tarama süresinin altına indirildiğinde
görüntüler üst üste biner; yeni istek ya atlanır ya da öncekiyle yarışır. Her iki durumda da
gerçekleşen aralık ayarlanandan büyük olur ve yapılandırmada yazan kayıp penceresi gerçeği
anlatmaz.

## Aralık Kararı

Üç ölçüm tek tabloda toplanır. Sayılar altmış bin yazmalık koşuma aittir.

| Aralık | Ortalama kayıp | En kötü kayıp | Disk yazımı | Kopyalanan giriş |
|---|---|---|---|---|
| 1.000 | 501 yazma | 1.000 yazma | 30 MB | 24.985 |
| 5.000 | 2.501 yazma | 5.000 yazma | 6 MB | 4.710 |
| 20.000 | 10.001 yazma | 20.000 yazma | 2 MB | 913 |

Karar, kaybedilen yazmanın ne olduğuna bakılarak verilir. Katalog önbelleği için yirmi binlik
aralık bile fazla korumadır: yiten girişler zaten kaynağından yeniden üretilebilir. Ödünç
sayaçları ve bekleme listesi için on bin yazmalık ortalama kayıp, kütüphanenin bir günlük
işlemine denk gelebilir ve bunun geri alınması elle yapılır.

Anlık görüntünün yapısal sınırı buradadır: aralık ne kadar kısaltılırsa kısaltılsın kayıp
penceresi sıfır olmaz, çünkü son görüntüden sonraki her yazma korumasızdır. Aralığı tarama
süresinin altına indirmek de bir işe yaramaz. Kayıp penceresini gerçekten kapatmak için
deponun tamamını değil, **her yazmanın kendisini** kaydeden bir biçim gerekir.

## Özet

- Anlık görüntü kalıcılığı deponun bütününü aralıklarla diske yazar; kayıp penceresinin
  ortalaması aralığın yarısı, en kötüsü aralığın kendisidir.
- Ölçümde bin yazmalık aralık ortalama kaybı 10.001'den 501'e indirdi ve bunun karşılığında
  disk yazımını 2 MB'tan 30 MB'a çıkardı; görüntü her seferinde deponun tamamını yazar.
- Görüntünün boyutu yazma sayısıyla değil anahtar sayısıyla büyür: 60.000 yazma 19.040 giriş
  bıraktı ve dosya 717.260 bayt oldu.
- Aynı veri bellekte 1.593.100 bayt tutar; aradaki fark diske gitmeyen üstveridir, bu yüzden
  dosya boyutundan bellek gereksinimi çıkarılamaz.
- Görüntü alırken duraklatmak 33.285 yazmayı bekletti, kopyalamak hiçbirini bekletmedi ama
  tepe 59.565 bayt fazladan tuttu; tepeyi aralık değil tarama süresindeki ayrı anahtar sayısı
  belirler.

## Sonraki Adım

Anlık görüntü, deponun bir **anındaki** hâlini yazar ve iki an arasında olan biteni yazmaz.
Kayıp penceresini kapatmanın tek yolu, durumun kendisi yerine duruma götüren yazmaları
kaydetmektir. Sonraki ders bunu ele alır: her yazma bir kayıt olarak dosyanın sonuna eklenir,
kurtarma bu kayıtları yeniden oynatır. Ölçülecek olan, kaydın yazma başına kaç bayt tuttuğu,
dosya sınırsız büyüdüğünde onu kısaltan yeniden yazımın ne kadar yer kazandırdığı ve
kayıtların diske ne sıklıkta eşzamanlanacağı seçiminin kayıp penceresiyle yazma maliyetini
nasıl karşı karşıya getirdiğidir.
