Slabá reference - Weak reference

v programování, a slabá reference je odkaz to nechrání referované objekt ze sbírky od Popelář, na rozdíl od silné reference. Odkazovaný objekt pouze slabými odkazy - což znamená „každý řetězec odkazů, který dosáhne objektu, obsahuje alespoň jeden slabý odkaz jako odkaz“ - je považován slabě dosažitelný, a lze s nimi zacházet jako nedosažitelný a tak mohou být shromažďovány kdykoli. Některé jazyky sbírané odpadky obsahují nebo podporují různé úrovně slabých odkazů, například C#, Jáva, Lisp, OCaml, Perl, Krajta[1] a PHP od verze 7.4[2].

Použití

Slabé reference mají řadu běžných případů použití. Při použití počítání referencí uvolňování paměti, slabé odkazy se mohou zlomit referenční cykly pomocí slabé reference pro odkaz v cyklu. Když má člověk asociativní pole (mapování, hash mapa), jehož klíče jsou (odkazy na) objekty, například pro uchování pomocných dat o objektech, použití slabých odkazů pro klíče se vyhne udržení objektů naživu jen kvůli jejich použití jako klíče. Když jeden má objekt, kde jsou registrovány další objekty, například v vzor pozorovatele (zejména v zpracování událostí ), pokud je zachován silný odkaz, objekty musí být výslovně zrušeny, jinak dojde k úniku paměti ( selhal problém posluchače ), zatímco slabý odkaz odstraňuje nutnost zrušení registrace. Když držíte data uložená v mezipaměti, která lze v případě potřeby znovu vytvořit, slabé odkazy umožňují opětovné získání mezipaměti, což účinně produkuje discardable paměť. Tento poslední případ (mezipaměť) se liší od ostatních, protože je lepší, aby objekty byly shromažďovány pouze v případě potřeby, a je tedy potřeba jemnějších rozdílů v rámci slabých odkazů, zde silnější forma slabého odkazu. V mnoha případech nemusí být slabé odkazy přímo použity, místo toho jednoduše použijte slabé pole nebo jiné kontejner jejichž klíče nebo hodnoty jsou slabými odkazy.

Sběr odpadu

Garbage collection se používá k vyčištění nepoužívaných objektů a tím ke snížení potenciálu úniky paměti a poškození dat. Existují dva hlavní typy sběru odpadků: trasování a počítání referencí. Schémata počítání referencí zaznamenávají počet odkazů na daný objekt a shromažďují objekt, když se počet odkazů stane nulovým. Počítání referencí nemůže sbírat cyklické (nebo kruhové) reference, protože najednou lze sbírat pouze jeden objekt. Skupiny vzájemně se odkazujících objektů, které nejsou přímo odkazovány jinými objekty a jsou nedosažitelné, se tak mohou stát trvale rezidentními; pokud aplikace neustále generuje takové nedosažitelné skupiny nedosažitelných objektů, bude to mít účinek a únik paměti. Slabé reference (reference, které se při počítání referencí nepočítají) lze použít k vyřešení problému kruhových referencí, pokud se referenčním cyklům vyhneme použitím slabých referencí pro některé z referencí ve skupině.

Velmi častým případem takových silných a slabých referenčních rozdílů jsou stromové struktury, například Model objektu dokumentu (DOM), kde jsou silné odkazy na rodiče, ale slabé jsou odkazy na rodiče. Například Apple Kakao rámec tento přístup doporučuje.[3] Ve skutečnosti, i když graf objektu není strom, může být stromová struktura často vynucena pojmem vlastnictví objektu, kde jsou vlastnické vztahy silné a tvoří strom, a nevlastnické vztahy jsou slabé a nejsou potřebné k vytvoření stromu - tento přístup je běžný v systému Windows C ++ (pre-C ++ 11), za použití surových ukazatelů jako slabých odkazů. Tento přístup má však nevýhodu, že neumožňuje schopnost detekovat, kdy byla nadřazená větev odebrána a odstraněna. Protože C ++ 11 standardu, byl přidán roztok pomocí shared_ptr a slabý_ptr, zděděný z Zvýšit rámec.

Slabé odkazy se také používají k minimalizaci počtu nepotřebných objektů v paměti tím, že umožňují programu označit, které objekty mají menší význam, pouze jejich slabým odkazováním.

Variace

Některé jazyky mají několik úrovní slabé referenční síly. Například, Jáva má, v pořadí klesající síly, měkký, slabý a přízrak odkazy definované v balík java.lang.ref.[4] Každý typ odkazu má přidruženou představu o dosažitelnosti. Sběratel odpadků (GC) používá typ dosažitelnosti objektu k určení, kdy má být objekt uvolněn. Pro GC je bezpečné uvolnit objekt, který je snadno dosažitelný, ale GC se může rozhodnout, že tak neučiní, pokud se domnívá, že JVM může ušetřit paměť (např. JVM má hodně nevyužitého haldy). GC uvolní slabě dosažitelný objekt, jakmile si ho GC všimne. Na rozdíl od ostatních typů odkazů nelze sledovat přízrakový odkaz. Na druhou stranu, fantomové odkazy poskytují mechanismus k upozornění programu, když byl objekt uvolněn (oznámení je implementováno pomocí ReferenceQueues).

V C # se slabé odkazy liší podle toho, zda sledují vzkříšení objektu nebo ne. U silných odkazů k tomuto rozlišení nedochází, protože objekty nejsou dokončeno pokud na ně mají nějaké silné odkazy. Ve výchozím nastavení v C # slabý odkaz nesleduje vzkříšení, což znamená, že slabý odkaz se neaktualizuje, pokud je objekt vzkříšen; tito se nazývají krátké slabé referencea jsou nazývány slabé odkazy sledující vzkříšení dlouhé slabé reference.[5]

Některé jazyky, které se neshromažďují, například C ++, poskytují slabé / silné referenční funkce jako součást podpory knihoven uvolňování paměti. Knihovna Boost C ++ poskytuje silné a slabé odkazy. Je chybou použít běžné ukazatele C ++ jako slabý protějšky z inteligentní ukazatele protože takové použití odstraní schopnost zjistit, kdy silný počet odkazů klesl na 0 a objekt byl odstraněn. Ještě horší je, že neumožňuje detekci toho, zda jiný silný odkaz již sleduje daný prostý ukazatel. To zavádí možnost mít dva (nebo více) inteligentních ukazatelů sledujících stejný prostý ukazatel (což způsobí poškození, jakmile jeden z těchto referenčních čísel inteligentních ukazatelů dosáhne 0 a objekt bude odstraněn).

Příklady

Slabé odkazy mohou být užitečné při uchovávání seznamu aktuálních proměnných, na které se v aplikaci odkazuje. Tento seznam musí mít slabé odkazy na objekty. V opačném případě, jakmile budou objekty přidány do seznamu, bude na ně odkazovat a budou přetrvávat po dobu trvání programu.

Jáva

Java 1.2 v roce 1998 zavedena[6] dva druhy slabých odkazů, jeden známý jako „soft reference“ (určený k použití pro udržování mezipamětí spravovaných pomocí GC, ale který v praxi na některých platformách s dynamickou hromadou jako Android nefunguje příliš dobře)[7]) a druhý jednoduše jako „slabý odkaz“. Rovněž přidal související experimentální mechanismus nazvaný „fantomové odkazy“ jako alternativu k nebezpečnému a neefektivnímu mechanismu finalise ().[8]

Pokud je vytvořen slabý odkaz, a pak jinde v kódu dostat() se používá k získání skutečného objektu, slabá reference není dostatečně silná, aby zabránila shromažďování odpadků, takže může být (pokud neexistují žádné silné odkazy na objekt), že dostat() najednou se začne vracet null.[9]

import java.lang.ref.WeakReference;veřejnost třída ReferenceTest {    veřejnost statický prázdnota hlavní(Tětiva[] args) hodí Přerušená výjimka {        Slabá reference r = Nový Slabá reference("Jsem tu");        Silný odkaz sr = Nový Silný odkaz("Jsem tu");        Systém.ven.tisk(„Before gc: r =“ + r.dostat() + ", static =" + sr.dostat());        Systém.gc();        Vlákno.spát(100);        // Pouze r.get () se stane null.        Systém.ven.tisk("Po gc: r =" + r.dostat() + ", static =" + sr.dostat());    }}

Další použití slabých odkazů je v písemné formě a mezipaměti. Například pomocí slabého hash mapa, lze do mezipaměti ukládat různé odkazované objekty pomocí slabé reference. Když běží garbage collector - když se například využití paměti aplikace dostane dostatečně vysoko - ty objekty v mezipaměti, které již nejsou přímo odkazovány jinými objekty, jsou odstraněny z mezipaměti.

Pokec

|a s1 s2|s1 := 'Ahoj' kopírovat.     „to je silná reference“s2 := 'svět' kopírovat.     „to je silná reference“A := WeakArray s:s1 s:s2.A printOn: Přepis. ObjectMemory sbírat Garbage.A printOn: Přepis.  "oba prvky stále existují"s1 := nula.              „silná reference zmizí“ ObjectMemory sbírat Garbage.A printOn: Přepis.  "první prvek pryč"s2 := nula.              „silná reference zmizí“ ObjectMemory sbírat Garbage.A printOn: Přepis.  "druhý prvek pryč"

Lua

slabá_tabulka = nastavitelný({}, {__mode="proti"})slabá_tabulka.položka = {}tisk(slabá_tabulka.položka)sbírat odpadky()tisk(slabá_tabulka.položka)

Objektiv C 2.0

v Cíl-C 2.0, nejen sběr odpadu, ale také automatické počítání referencí budou ovlivněny slabými odkazy. Všechny proměnné a vlastnosti v následujícím příkladu jsou slabé.

@rozhraní WeakRef : NSObject{    __slabý NSString *str1;    __unsafe_unretained NSString *str2;}@vlastnictví (natomatomický, slabý) NSString *str3;@vlastnictví (natomatomický, unsafe_unretained) NSString *str4;@konec

Rozdíl mezi slabý (__slabý) a unsafe_unretained (__unsafe_unretained) je, že když je objekt, na který proměnná ukazuje, uvolněn, ať už se hodnota proměnné změní nebo ne. slabý ty budou aktualizovány na nula a unsafe_unretained jeden zůstane nezměněn, jako a visící ukazatel. The slabý od roku se do Objective-C přidávají odkazy Mac OS X 10.7 „Lion“ a iOS 5, dohromady s Xcode 4.1 (4.2 pro iOS) a pouze při použití ARC. Pouze starší verze systémů Mac OS X, iOS a GNUstep unsafe_unretained odkazy jako slabé.

Vala

třída Uzel {    veřejnost slabý Uzel předchozí; // slabá reference se používá, aby se zabránilo cyklickým odkazům mezi uzly dvojnásobně propojeného seznamu    veřejnost Uzel další;}

Krajta

>>> import slabá reference>>> import gc>>> třída Vejce:...     def spam():...         tisk("Jsem naživu!")...>>> obj = Vejce()>>> slabý_obj = slabá reference.ref(obj)>>> slabý_obj().spam()Jsem naživu!>>> obj = "Něco jiného">>> gc.sbírat()35>>> slabý_obj().spam()Traceback (poslední hovor poslední):  Soubor , řádek 1, v <module>AttributeError: Objekt „NoneType“ nemá atribut „spam“

Viz také

Reference

  1. ^ 8.8. slabá reference - Slabé reference, Standardní knihovna Pythonu
  2. ^ https://www.php.net/manual/en/class.weakreference.php
  3. ^ „Praktická správa paměti“. developer.apple.com.
  4. ^ Nicholas, Ethan (4. května 2006). „Porozumění slabým referencím“. java.net. Citováno 1. října 2010.
  5. ^ Goldshtein, Zurbalev a Flatow 2012, str.131.
  6. ^ „WeakReference (Java Platform SE 7)“. docs.oracle.com.
  7. ^ „SoftReference - vývojáři pro Android“. developer.android.com.
  8. ^ „PhantomReference (Java Platform SE 7)“. docs.oracle.com.
  9. ^ https://web.archive.org/web/20110303225354/http://weblogs.java.net/blog/2006/05/04/understanding-weak-references Příklady Java

externí odkazy

C ++

Jáva

PHP

Krajta