3 ms·
Haven't done much Perl hacking, good to know it's more-or-less pure reference counting. Paging can occur as a consequence of copying a reference. var p1 =
by kmontrose 15y ago
Haven't done much Perl hacking, good to know it's more-or-less pure reference counting.
Paging can occur as a consequence of copying a reference.
var p1 = *A // let p1 be a reference to A
// something in the interim
var p2 = p1 // create a new reference to A via p1
If A is no longer paged in incrementing its reference count (as a consequence of copying p1 into p2) can cause a page fault. There's are also gotchas with destroying references such as a collection having to effectively iterate over its contents to decrement each reference count, again possibly leading to additional paging.
This assumes an object carries its reference count with it, which every reference counting system I'm aware of does. I suppose you could technically keep reference counts in a common space, though growing that would be a bit rough.
A GC isn't a magic bullet or anything, but they don't need to cause any paging as a result of reference changes until a sweep; and even then, they only need to page in the live set which is more likely to be resident in memory.
I'm... skeptical Apple's introduction of ARC is really performance oriented. Seems more like they tried and failed to build a workable GC for Objective-C with Tiger. Haven't worked with much Objective-C since 10.4 though, so I'm not completely settled either way.
- mst 15y agoAh, the copying part, yes - but then again if I'm doing that, I'd expect to be doing so in order to access A at which point I already needed that bit of memory. The collection thing I can definitely see though. One thing I've never quite worked out is - without reference counting, how do you handle timely destruction? I know that if I do something like: { my $x = foo(); ... } then $x will be destroyed at the exact point the } is hit, or that an exception unwinds the stack past this point. That lets me do all sorts of nice things like rolling back a transaction automatically, throwing a warning if some task was expected to be completed but hasn't been, and other bits and pieces. In a mark-and-sweep GC language, presumably there's some other additional feature that needs to be implemented in order to provide this?
- kmontrose 15y agoWell, there are certainly cases where you grab a reference speculatively; anything where you need > N in a collection to act on, for instance, but don't know how many items there are yet (such as when you're reading from a stream). There's also the "early return" case, where you'd grab reference say A, B, and C but only dereference C in code that runs if A and B failed some condition. The equivalent to timely destruction in C# is a using statement combined with implementing IDisposable. using(var stream = File.Open(somePath)) { // use stream to do whatever } This is syntactic sugar for a try{ } finally { } (that also exists in Java) that calls Dispose() in finally. You do any cleanup you need to in Dispose(), things like releasing file handles. The only way to dodge that Dispose() is to tear the execution thread down, which generally means the process is gone with it. C# classes (but not structs) can also declare destructors, but their execution schedule isn't guaranteed; they're useful for making absolutely sure resources are released eventually, Dispose() is preferred for timing and performance.