23.10.2024

0

Like

22

Views

Swift’te Bellek Yönetimi (Memory Management in Swift)

iOS uygulamaları geliştirirken bellek yönetimi, uygulamanızın performansını optimize etmek ve çökme sorunlarını önlemek için önemli bir konudur. Bu yazıda, iOS’ta bellek yönetimini derinlemesine ele alacağız.

Memory Management Nedir ?

Bellek yönetimi, bir uygulamanın belleği verimli bir şekilde tahsis etmesi ve serbest bırakması işlemidir. Doğru memory management kullanımı uygulamanın performansını, bellekteki verilerin doğru yönetilmesini, kaynakların verimli kullanılmasını sağlar.

iOS’ta iki farklı bellek yönetim modeli vardır : MRC ve ARC.

  • MRC (Manuel Referans Sayma)
  • ARC (Otomatik Referans Sayma)


Automatic Reference Counting (ARC)

Swift, uygulamanızın bellek kullanımını izlemek ve yönetmek için ARC kullanır. ARC, nesnelerin referanslarını otomatik olarak takip eder ve artık kullanılmadığında belleği serbest bırakır.

ARC’nin nasıl çalıştığını inceleyelim:

  • Bir nesne oluşturduğunuzda referans sayısı 1 olarak başlar.
  • Başka bir nesne o nesneye referans verdiğinde, referans sayısı artar.
  • Bir nesneye olan referans kaldırıldığında, referans sayısı azalır ve 0'a ulaştığında, ARC nesneyi serbest bırakır.
  • Automatic Reference Counting (ARC), yalnızca strong referansları sayar

class Product {
let name: String

init(name: String) {
self.name = name
print("\(name) ürün bellekte oluşturuldu")
}

deinit {
print("\(name) ürün bellekte temizlendi")
}
}

var product1: Product? = Product(name: "Telephone") //reference counter = 1
var product2: Product? = product1 //reference counter = 2

product1 = nil //reference counter = 1
product2 = nil //reference counter = 0


Yukarıda ki kod bloğunun çıktısı:

Telephone ürün bellekte oluşturuldu

Telephone ürün bellekte temizlendi


Referans Türleri

  • Strong Referans: Bir değişken tanımlandığında default olarak strong yapıdadır. Strong bir değişkene sahip olunduğunda, referans sayısını artırır.
  • Weak Referans: Weak referans, referans sayısını artırmaz. Eğer bir nesne yalnızca weak referanslar tarafından referans alıyorsa, bu nesne bellekte kalmaz ve otomatik olarak nil olur. Bu, retain cycle’ ları önlemek için idealdir.
  • Unowned Referans: Unowned referans, referans sayısını artırmaz ve referans verilen nesne her zaman var olmalıdır. Eğer nesne yoksa ve unowned referansa erişilirse, uygulama çökebilir.


Retain Cycles

ARC görevini yerine getirirken bazı durumlarda retain cycle oluşur. Retain cycle, iki veya daha fazla nesnenin birbirine güçlü (strong) referansla bağlı kalması durumunda oluşur ve bu nesneler bellekten temizlenemez. Bu durum bellek sızıntılarına (memory leak) yol açar.


class Product {
let name: String
var seller: Seller?

init(name: String) {
self.name = name
print("\(name) ürün bellekte oluşturuldu")
}

deinit {
print("\(name) ürün bellekte temizlendi")
}
}

class Seller {
let name: String
var product: Product?

init(name: String) {
self.name = name
print("\(name) satıcı bellekte oluşturuldu")
}

deinit {
print("\(name) satıcı bellekte temizlendi")
}
}

var product: Product? = Product(name: "Camera")
var seller: Seller? = Seller(name: "Emily")

product?.seller = seller
seller?.product = product //Burada retain cycle oluşur.

product = nil
seller = nil


Yukarıda ki kod bloğunun çıktısı:

Camera ürün bellekte oluşturuldu

Emily satıcı bellekte oluşturuldu.


Yukarıda ki kod örneğine bakalım:

  • Product nesnesi Seller nesnesine, Seller nesnesi de Product nesnesine güçlü (strong) bir referans tutmaktadır.
  • Her iki nesne de birbirine referans vermekte ve referans sayıları asla sıfıra düşmemektedir. Sonuç olarak, bu nesneler bellekten temizlenmez ve bellek sızıntısı oluşur.
  • Retain cycle oluştuğu için Product nesnesi de Seller nesneside bellekten silinemiyor.

Peki bunun çözüm yolu nedir?

Retain cycle’ ı önlemek için yapılabilecek bazı şeyler şunlardır:

  • Weak Referans Kullanımı
  • Unowned Referans Kullanımı
  • Closure’ larda [weak self] veya [unowned self] Kullanımı
  • Delegate Tasarım Deseninde Weak Referans Kullanmak
  • MRC (Manuel Memory Management) Yöntemi

Yukarıda ki kod örneğinde ki retain cycle’ ı çözmek için strong referans oluşturan nesnelerden birini weak yapmamız yeterli olacaktır. Bu retain cycle önlemek için Product sınıfında ki seller özelliğini weak olarak tanımlayabiliriz.

Unowned tanımlasak da aynı sonucu alabilirdik. Ancak dikkatli olmak lazım çünkü unowned referanslar, referans verdikleri nesnenin yok olup olmadığını kontrol etmez. Eğer unowned bir referansa erişildiğinde referans verilen nesne artık mevcut değilse, uygulama çöker. Eğer Product her zaman bir Seller’ a sahip olacaksa ve bu ilişki boyunca Seller’ ın yaşam döngüsü Product’ dan bağımsız olarak garanti ediliyorsa, unowned referansı kullanmak mantıklı olabilir.

class Product {
let name: String
weak var seller: Seller?

init(name: String) {
self.name = name
print("\(name) ürün bellekte oluşturuldu")
}

deinit {
print("\(name) ürün bellekte temizlendi")
}
}

class Seller {
let name: String
var product: Product?

init(name: String) {
self.name = name
print("\(name) satıcı bellekte oluşturuldu")
}

deinit {
print("\(name) satıcı bellekte temizlendi")
}
}

var product: Product? = Product(name: "Camera")
var seller: Seller? = Seller(name: "Emily")

product?.seller = seller
seller?.product = product //Biri weak olduğu için retain cycle oluşmaz.

product = nil
seller = nil

Yukarıda ki kod bloğunun çıktısı:

Camera ürün bellekte oluşturuldu

Emily satıcı bellekte oluşturuldu.

Emily satıcı bellekte temizlendi.

Camera ürün bellekte temizlendi.


Şimdi gelelim retain cycle’ ın en yaygın sonuçlarından biri olan bellek sızıntısına..

Memory Leak (Bellek Sızıntısı)

Memory leak, artık kullanılmayan bir nesnenin referans sayısının sıfıra düşmemesi ve bu nedenle bellekten serbest bırakılmaması durumudur. Memory leak oluşumu sistemin belleğini tüketir ve uygulamanın performansını düşürüp çökmesine bile sebep olabilir.

Xcode, memory leak’ leri tespit etmek için birkaç araca sahiptir. Bunlardan en çok tercih edilenlerden biri : Instruments

Instruments

Xcode’un Instruments aracındaki Leaks aracı, bellek sızıntılarını tespit etmek için özel olarak tasarlanmıştır.

Instruments ile Memory Leak Bulma Adımları:

  • Xcode Projenizi Açın
  • Product > Profile yolunu izleyin.
  • Instruments aracı açıldığında, Leaks seçeneğini seçin.
  • Profil işlemini başlatın.
  • Instruments, uygulamanız çalışırken bellek sızıntılarını gerçek zamanlı olarak izler ve tespit eder.


Swift
İleri Seviye Swift

Comments

You need to log in to be able to comment!

Şehriban Yıldırım

Yazılım Mühendisliği mezunuyum, Swift ile mobil uygulama geliştiriyorum ve bu alanda kendimi geliştirmeye devam ediyorum. https://medium.com/@sehribanyildirim051

Location

İstanbul, TR

Education

Yazılım Mühendisliği - Fırat Üniversitesi

Job Experience

Intern - Bera Ar-Ge Yazılım

Intern - Mobillium

© 2021 Patika Dev

facebook
twitter
instagram
youtube
linkedin

Disclaimer: The information /programs / events provided on https://patika.dev and https://risein.com are strictly for upskilling and networking purposes related to the technical infrastructure of blockchain platforms. We do not provide financial or investment advice and do not make any representations regarding the value, profitability, or future price of any blockchain or cryptocurrency. Users are encouraged to conduct their own research and consult with licensed financial professionals before engaging in any investment activities. https://patika.dev and https://risein.com disclaim any responsibility for financial decisions made by users based on information provided here.