Díky za upozornění. Asi jsem to napsal nejasně, ale myslel jsem to tak, že funkčnost není zaručena v obecném případě (bez ohledu na jazyk), proto to je v Rustu řešeno.
A ano, v Rustu by to z normálním počitadlem referencí nešlo přeložit. Asi to doplním aspoň sem do diskuze, co by se stalo při náhradě Arc za "normální" Rc:
error[E0277]: the trait bound `std::rc::Rc<Complex>: std::marker::Send` is not satisfied
--> test.rs:52:9
|
52 | thread::spawn(move || {
| ^^^^^^^^^^^^^
|
= note: `std::rc::Rc<Complex>` cannot be sent between threads safely
= note: required because it appears within the type `ComplexNumberOwner`
= note: required because it appears within the type `[closure@test.rs:52:23: 55:10 owner:ComplexNumberOwner]`
= note: required by `std::thread::spawn`
Hlavní důvod pro GC oproti počítání referencí je ten, že počítání referencí neřeší cyklus. Pokud odkazuji z objektu A na objekt B a současně opačně z objektu B na objekt A počitadlem referencí, tak se to nikdy samo neuvolní. GC tohle umí detekovat a uvolnit i cykly. Samozřejmě za cenu nějaké režije navíc. Atomické počitadlo ale taky není zadarmo, někdy může být rychlejší GC a někdy zase počítání referencí, záleží na konktétní situaci.
Obecne bych si dovolil tvrdit ze GC bude ve vetsine pripadu rychlejsi, vyhodou RC je v podstate jen to ze nezpusobuje takove latence, coz je pro nektere aplikace kriticke a mnohem dulezitejsi nez celkova rychlost. Dale ma vetsinou RC ci ARC nizsi naroky na pamet. Samozrejme jde o to o jakem GC se bavime
rekneme mark and sweep v konfiguraci, kdy je heap rozdeleny na young+old generations (jako ma Java). Ale neni to tak jednoduche, JVM ma jeste TLAB, neboli objekty se alokuji defaultne tak, ze nejsou sdileny (v thread-local bufferu). Popravde - me to trosku pripada, jako narovnavak na ohybak (vse je na heapu, zadny objekt na stacku, proto pro uplne lokalni objekty stejne potrebujeme TLAB).
Taky jde o to, ze pokud mam RC, tak zruseni objektu vetsinou probiha ASAP, aby se pocitadla spravne dekrementovala (popr. by asi musela existovat nejaka fronta objektu pripravenych pro mazani?). Neni to asi nutnost, ale zatim jsem to tak videl reseno. Naproti tomu nejaky bitovy flag v mark and sweep; to si klidne muze pockat na GC thready nekdy v budoucnosti.