Python 2.0

Hisao Suzuki suzuki611 at okisoft.co.jp
Fri Jun 4 03:25:46 EDT 1999


In article <14166.61071.201719.405639 at bitdiddle.cnri.reston.va.us>,
Jeremy Hylton <jeremy at cnri.reston.va.us> wrote:
| To the contrary, the community is too busy using Python to bother with 
| all these silly discussions about changing Python.  The fact that I'm
| posting in this threads is... ummm... the exception that proves the
| rule.

Yes, we are too busy using Python to bother with some fancy
ideas, in particular, those of some other (superior?) languages.

| Most of the volume has been a vigorous but unenlightening back and
| forth about garbage collection.  I've for one have concluded that
| there have been enough papers written about garbage collection that,
| for any particular argument against GC, there exists at least one
| paper describing a system for which that argument doesn't apply.  
| 
| Of course, none of that has anything to do with Python.  I'm tired of
| hearing what GC can do in theory.  I'd be happy to hear about some
| actual experience implementing a GC system for Python.  Otherwise,
| let's put this on to bed.

Me too.  And I am afraid that some evangelists would do nothing
but _only_ point out Python's some so-called fault in order to
drive us into convert to their favorite or invented language...

Anyway, as you say, I'd think that we need an actual experience.

The following might be served as the very basic, half-baked
demonstration of mark-and-sweep garbage collection.  (Actually
it does not collect any garbages.  It just report them.)

------8<------8<------8<------8<------8<------8<------8<------8<------
import sys
from types import *

def get_referred_instances():
    """Collect all the validly referred instances [PRELIMINARY VERSION].

    Return a dictionary of id_of_instance:name_of_instance, where
    id_of_instance is an integer value returned by id(instance) and
    name_of_instance is a human-readable string generated in some ad
    hoc way.

    Note that the reference counting of the interpreter does not
    affected by this function.  The return value does not have
    instances themselves but id values of them.
    """
    instances = {}
    dicts = {}
    _get_referred_sub(sys.modules, "", dicts, instances)
    return instances

def _get_referred_sub(val, name, dicts, instances):
    if isinstance(val, DictionaryType):
	for key, obj in val.items():
	    _get_referred_sub(key, '%s\'s key' % name,
			      dicts, instances)
	    _get_referred_sub(obj, '%s[%s]' % (name, key),
			      dicts, instances)
    elif isinstance(val, ListType) or isinstance(val, TupleType):
        for i, obj in map(None, range(len(val)), val):
	    _get_referred_sub(obj, '%s[%d]' % (name, i),
			      dicts, instances)
    else:
	# instance, class, module, ...
	if isinstance(val, InstanceType): instances[id(val)] = name
	elif isinstance(val, ModuleType): name = val.__name__
	try: d = val.__dict__
	except: pass
	else:
	    _id = id(d)
	    if not dicts.has_key(_id):
		dicts[_id] = name
		for key, obj in d.items():
		    key = name + '.' + key
		    _get_referred_sub(obj, key, dicts, instances)

if __name__ == '__main__':
    class A:				# sample class
	instances = []
	def __init__(self): A.instances.append(id(self))
	def __del__(self): A.instances.remove(id(self))
    a = A(); b = A(); a.b = b; b.a = a	# construct circular references
    x = [A(), A(), A()]

    print "Referred instances are", get_referred_instances()
    print "Class A instances are", A.instances
    print "Delete variables a, b, and x."
    del a, b, x
    print "Now, class A instances are", A.instances

    # Mark all objects referred.
    marked = get_referred_instances().keys()
    # Then, sweep the garbage of class A.
    garbages = []
    for _id in A.instances:
	if _id not in marked:
	    garbages.append(_id)
    print "Unreferred (= of garbage) A instances are", garbages
------8<------8<------8<------8<------8<------8<------8<------8<------

And this is the result:

Referred instances are {135060000: '__main__.a.b.a', 135060024: '__main__.b', 135060128: '__main__.x[2]', 135060072: '__main__.x[1]', 134996472: 'os.environ', 135060048: '__main__.x[0]'}
Class A instances are [135060000, 135060024, 135060048, 135060072, 135060128]
Delete variables a, b, and x.
Now, class A instances are [135060000, 135060024]
Unreferred (= of garbage) A instances are [135060000, 135060024]

--===-----========------------- Sana esprimo naskas sanan ideon.
SUZUKI Hisao            suzuki611 at okisoft.co.jp, suzuki at acm.org.




More information about the Python-list mailing list