Zayıf referans - Weak reference

Gelen bilgisayar programlama , bir zayıf başvuruya bir olan referans başvurulan korumaz nesneyi bir yan koleksiyonundan çöp toplayıcı güçlü referans aksine. Başvurulan bir nesne sadece zayıf referansları ile - kabul edilir - anlamına gelen "nesne ulaşır referansların her zincir bir bağlantı olarak en az bir zayıf referans içeren" zayıf ulaşılabilir , ve olarak tedavi edilebilir ulaşılamaz ve böylece herhangi bir zamanda toplanabilir. 7.4 sürümünden beri C# , Java , Lisp , OCaml , Perl , Python ve PHP gibi bazı çöp toplanmış diller çeşitli seviyelerde zayıf referansları içerir veya destekler .

kullanır

Zayıf referansların birkaç yaygın kullanım durumu vardır. Kullanırken referans sayma çöp toplama, zayıf başvuruları kırabilir başvuru çevreleri döngüsünde bir bağlantı için zayıf bir referansı kullanılarak,. Anahtarları nesneler (referansları) olan bir ilişkisel diziye (eşleme, karma harita) sahip olduğunuzda, örneğin nesneler hakkında yardımcı verileri tutmak için, anahtarlar için zayıf referanslar kullanmak, yalnızca anahtar olarak kullanılmaları nedeniyle nesneleri canlı tutmaktan kaçınır. Birinin gözlemci modelinde olduğu gibi (özellikle olay işlemede ) diğer nesnelerin kaydedildiği bir nesnesi olduğunda, güçlü bir referans tutuluyorsa, nesnelerin açıkça kaydının kaldırılması gerekir, aksi takdirde bir bellek sızıntısı meydana gelir ( geçmiş dinleyici sorunu ), zayıf bir referans, kaydı silme ihtiyacını ortadan kaldırır. Gerekirse yeniden oluşturulabilecek önbelleğe alınmış verileri tutarken, zayıf referanslar önbelleğin geri alınmasına izin vererek etkin bir şekilde atılabilir bellek üretir. Bu son durum (bir önbellek) diğerlerinden farklıdır, çünkü nesnelerin yalnızca gerektiğinde çöp toplanması tercih edilir ve bu nedenle zayıf referanslar içinde daha ince ayrımlara, burada daha güçlü bir zayıf referansa ihtiyaç vardır. Çoğu durumda, zayıf referansların doğrudan kullanılması gerekmez, bunun yerine sadece zayıf bir dizi veya anahtarları veya değerleri zayıf referanslar olan başka bir kap kullanılır .

Çöp toplama

Çöp toplama, kullanılmayan nesneleri temizlemek ve böylece bellek sızıntısı ve veri bozulması olasılığını azaltmak için kullanılır . İki ana çöp toplama türü vardır: izleme ve referans sayımı . Referans sayma şemaları, belirli bir nesneye yapılan referansların sayısını kaydeder ve referans sayısı sıfır olduğunda nesneyi toplar. Referans sayma, bir seferde yalnızca bir nesne toplanabileceğinden, döngüsel (veya döngüsel) referansları toplayamaz. Diğer nesneler tarafından doğrudan referansta bulunulmayan ve erişilemeyen karşılıklı referans veren nesne grupları böylece kalıcı olarak yerleşik hale gelebilir; bir uygulama sürekli olarak bu tür erişilemeyen nesne grupları oluşturuyorsa, bu bir bellek sızıntısı etkisine sahip olacaktır . Grup içindeki bazı referanslar için zayıf referanslar kullanılarak referans döngülerinden kaçınılırsa, zayıf referanslar (referans sayımında sayılmayan referanslar), dairesel referanslar sorununu çözmek için kullanılabilir.

Bu tür güçlü ve zayıf referans ayrımlarının çok yaygın bir örneği, üst öğeden alt öğeye başvuruların güçlü, ancak alt öğeden üst öğeye başvuruların zayıf olduğu Belge Nesne Modeli (DOM) gibi ağaç yapılarındadır . Örneğin, Apple'ın Kakao çerçevesi bu yaklaşımı önerir. Gerçekten de, nesne grafiği bir ağaç olmadığında bile, mülkiyet ilişkilerinin güçlü olduğu ve bir ağaç oluşturduğu ve sahiplik dışı ilişkilerin zayıf olduğu ve ağacı oluşturmak için gerekli olmadığı durumlarda, genellikle bir ağaç yapısı nesne sahipliği kavramı tarafından dayatılabilir. – bu yaklaşım, ham işaretçileri zayıf referanslar olarak kullanan C++'da (C++11 öncesi) yaygındır . Ancak bu yaklaşımın dezavantajı, bir üst dalın ne zaman kaldırıldığını ve silindiğini tespit etme yeteneğine izin vermemesidir. C++11 standardından bu yana, Boost kitaplığından devralınan, paylaşılan ptr ve zayıf ptr kullanılarak bir çözüm eklendi .

Zayıf referanslar ayrıca, programın hangi nesnelerin önemsiz olduğunu sadece zayıf referanslarla belirtmesine izin vererek bellekteki gereksiz nesnelerin sayısını en aza indirmek için kullanılır.

Varyasyonlar

Bazı dillerde birden çok düzeyde zayıf referans gücü vardır. Örneğin, Java , azalan güç sırasıyla java.lang.ref paketinde tanımlanan soft , zayıf ve hayali referanslara sahiptir . Her referans türünün ilişkili bir erişilebilirlik kavramı vardır. Çöp toplayıcı (GC), nesnenin ne zaman serbest bırakılacağını belirlemek için nesnenin erişilebilirlik türünü kullanır. GC'nin yumuşak bir şekilde erişilebilen bir nesneyi serbest bırakması güvenlidir, ancak GC, JVM'nin belleği yedekleyebileceğine inanıyorsa bunu yapmamaya karar verebilir (örneğin, JVM'de çok fazla kullanılmayan yığın alanı vardır). GC, zayıf erişilebilir bir nesneyi, GC nesneyi fark eder etmez serbest bırakacaktır. Diğer referans tiplerinden farklı olarak, bir hayali referans takip edilemez. Öte yandan, hayali referanslar, bir nesne serbest bırakıldığında programı bilgilendirmek için bir mekanizma sağlar (bildirim ReferenceQueues kullanılarak uygulanır).

C#'da zayıf referanslar, nesne dirilişini izleyip izlememelerine göre ayırt edilir . Bu ayrım, güçlü referanslar için oluşmaz, çünkü nesneler kendilerine herhangi bir güçlü referansları varsa kesinleştirilmez . Varsayılan olarak, C#'da zayıf başvuru yeniden dirilişi izlemez, yani bir nesne yeniden canlandırılırsa zayıf bir başvuru güncellenmez; bunlara kısa zayıf referanslar denir ve dirilişi izleyen zayıf referanslara uzun zayıf referanslar denir .

C++ gibi bazı çöp toplamayan diller, çöp toplama kitaplıklarını desteklemenin bir parçası olarak zayıf/güçlü başvuru işlevselliği sağlar. Boost C++ kitaplığı, güçlü ve zayıf referanslar sağlar. Akıllı işaretçilerin zayıf karşılıkları olarak normal C++ işaretçilerini kullanmak bir hatadır çünkü bu tür kullanım, güçlü referans sayısının 0'a ne zaman gittiğini ve nesnenin ne zaman silindiğini algılama yeteneğini ortadan kaldırır . Daha da kötüsü, başka bir güçlü referansın belirli bir düz işaretçiyi zaten izleyip izlemediğinin saptanmasına izin vermez. Bu, aynı düz işaretçiyi izleyen iki (veya daha fazla) akıllı işaretçiye sahip olma olasılığını sunar (bu, bu akıllı işaretçilerden birinin referans sayısı 0'a ulaştığında ve nesne silindiğinde bozulmaya neden olur).

Örnekler

Zayıf referanslar, uygulamada referans verilen mevcut değişkenlerin bir listesini tutarken faydalı olabilir. Bu listenin nesnelere zayıf bağlantıları olmalıdır. Aksi takdirde, nesneler listeye eklendiğinde, liste tarafından referans alınır ve program süresince devam eder.

Java

1998'de Java 1.2, biri “yumuşak referans” olarak bilinen iki tür zayıf referans sundu (GC tarafından yönetilen bellek içi önbellekleri korumak için kullanılması amaçlandı, ancak dinamik yığın içeren bazı platformlarda pratikte çok iyi çalışmıyor) Android gibi) ve diğeri sadece “zayıf referans” olarak. Ayrıca tehlikeli ve verimsiz finalize() mekanizmasına alternatif olarak “hayalet referanslar” olarak adlandırılan ilgili bir deneysel mekanizma ekledi.

Zayıf bir başvuru oluşturulursa ve daha sonra get()asıl nesneyi almak için kodun başka bir yerinde kullanılırsa, zayıf başvuru çöp toplamayı önleyecek kadar güçlü değildir, bu nedenle (nesneye güçlü referanslar yoksa) şu şekilde olabilir: get()aniden null döndürmeye başlar.

import java.lang.ref.WeakReference;

public class ReferenceTest {
    public static void main(String[] args) throws InterruptedException {
        WeakReference r = new WeakReference("I'm here");
        StrongReference sr = new StrongReference("I'm here");
        System.out.println("Before gc: r=" + r.get() + ", static=" + sr.get());
        System.gc();
        Thread.sleep(100);

        // Only r.get() becomes null.
        System.out.println("After gc: r=" + r.get() + ", static=" + sr.get());
    }
}

Zayıf referansların başka bir kullanımı da önbellek yazmaktır . Örneğin, zayıf bir karma harita kullanarak, bir zayıf referans yoluyla çeşitli referans verilen nesneleri önbellekte saklayabilir. Çöp toplayıcı çalıştığında - örneğin uygulamanın bellek kullanımı yeterince arttığında - artık diğer nesneler tarafından doğrudan başvurulmayan bu önbelleğe alınmış nesneler önbellekten kaldırılır.

küçük konuşma

|a s1 s2|

s1 := 'hello' copy.     "that's a strong reference"
s2 := 'world' copy.     "that's a strong reference"
a := WeakArray with:s1 with:s2.
a printOn: Transcript. 
ObjectMemory collectGarbage.
a printOn: Transcript.  "both elements still there"

s1 := nil.              "strong reference goes away" 
ObjectMemory collectGarbage.
a printOn: Transcript.  "first element gone"

s2 := nil.              "strong reference goes away" 
ObjectMemory collectGarbage.
a printOn: Transcript.  "second element gone"

Lua

weak_table = setmetatable({}, {__mode="v"})
weak_table.item = {}
print(weak_table.item)
collectgarbage()
print(weak_table.item)

Amaç-C 2.0

In Objective-C 2.0, çöp toplama, aynı zamanda sadece otomatik referans sayma zayıf referanslar tarafından etkilenecektir. Aşağıdaki örnekteki tüm değişkenler ve özellikler zayıftır.

@interface WeakRef : NSObject
{
    __weak NSString *str1;
    __unsafe_unretained NSString *str2;
}

@property (nonatomic, weak) NSString *str3;
@property (nonatomic, unsafe_unretained) NSString *str4;

@end

weak( __weak) ve unsafe_unretained( __unsafe_unretained) arasındaki fark , değişkenin işaret ettiği nesne serbest bırakıldığında, değişkenin değerinin değişip değişmeyeceğidir. weakolanlar güncellenecek nilve unsafe_unretainedbiri sarkan bir işaretçi olarak değişmeden bırakılacak . weakReferanslar beri Objective-C eklenir Mac OS X 10.7 "Aslan" ve iOS 5 ile birlikte, Xcode 4.1 (iOS için 4.2) ve sadece ARC kullanırken. Mac OS X, iOS ve GNUstep'in eski sürümleri, yalnızca unsafe_unretainedzayıf olanlar olarak referansları destekler .

vala

class Node {
    public weak Node prev; // a weak reference is used to avoid circular references between nodes of a doubly-linked list
    public Node next;
}

piton

>>> import weakref
>>> import gc
>>> class Egg:
...     def spam(self):
...         print("I'm alive!")
...
>>> obj = Egg()
>>> weak_obj = weakref.ref(obj)
>>> weak_obj().spam()
I'm alive!
>>> obj = "Something else"
>>> gc.collect()
35
>>> weak_obj().spam()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'spam'

Ayrıca bakınız

Referanslar

Dış bağlantılar

C++

Java

PHP

piton