-
Appel's scheme will not work for weakly-typed or polymorphic languages.
For example, let's suppose Appel's algorithm is traversing the type graph
and a data structure and finds that a particular field of the data structure
is an INTEGER (according to the type graph). In a weakly typed language
such as C, this field could contain anything that would fit in the "INTEGER".
Thus, the garbage collector would not know whether to treat that field
as a pointer or as an integer. Similarly, let's suppose that the
above-mentioned field was of type REF T. In a polymorphic type system,
this field could either point to an object of type T or any subtype of
T. So once again, the garbage collector will not know what the field
points to.
-
(i) time spent doing allocation will be less for scheme 1 since it just
needs to do check and bump a pointer. Scheme II needs to search a
free list (note: an allocation may trigger a garbage collection but that
is a "deallocation" cost and thus will be compared to explicit deallocation).
(ii) time spent doing deallocation. Scheme II needs to explicitly
free each garbage object, and thus does work proportional in the size and
number of dead objects. Scheme I copies the reachable objects and
thus does work proportional in the number of reachable objects per garbage
collection. If most objects are short-lived, Scheme I will do much
less work than Scheme II. If most objects are long-lived, then the
balance may shift in favor of Scheme II since Scheme I will need to copy
these long lived objects back and forth every garbage collection.
(iii)paging behavior. Scheme I compacts the reachable objects and
thus will have a smaller memory footprint, probably leading to better paging
behavior than Scheme II. On the other hand, during garbage collection,
Scheme I will touch objects all over memory and thus the paging behavior
during garbage collection may neutralize the benefits of compaction.
The bottom line is that it depends on whether objects are short lived or
long lived, because if they are short lived, Scheme I will not touch many
pages during gc.
-
After the statement "l1 = quicksort(lt)", the variable "lt" is dead--i.e.,
it will not be accessed again in the future. If the garbage collector
has this information then even though lt contains a pointer, the gc does
not need to consider "lt" as a root variable. In other words,
a garbage collector that does not have liveness information will keep the
list pointed to by "lt" around for the lifetime of the enclosing instantiation
of quicsort (and that lifetime corresponds to the time taken to sort the
entire list passed to quicksort). If on the other hand, the collector
has the liveness information, it will be able to reclaim the list pointed
to by lt as soon as quicksort(lt) returns.
-
persistence independence: if this is violated, then the programmer
would have to worry about writing separate code for persistent and non-persistent
objects.
data-type orthogonality: if this is violated, the programmer would
have to declare two distinct sets of classes, one set for persistent objects
and one set for non-persistent objects. This could also potentially
lead to problems if the user creates pointers from persistent to non-persistent
objects. Chances are that if this principle is violated, the principle
of persistence independence has also been violated.
persistence identification: if this is violated, then the programmer can
end up creating pointers from persistent to transient objects, which will
potentially manifest itself later as dangling pointer bugs.