last minute GC questions

I've got two last minute questions. Does it look to you like I checked in all of the changes that you and Vladimir discussed? Might we change the strategy for deciding when to collect? There are two parts of the strategy that could probably change. The first is what kind of allocation events we count to determine when to collect. Right now, the gc is counting the net effect of allocations and deallocations. This isn't effective for at least a couple of cases. If we allocate N objects and don't deallocate anything, then no garbage is going to be created. If we have many objects currently allocated and then dealloc N objects without allocating any, we could create collectible garbage, but the collector won't run because there haven't been any allocations. It seems to me that counting deallocations only would be more effective. It is only the deallocations that cause a live object to become garbage. The other part of the strategy that might be changed is the collection frequency. Right now, the threshold is 100 net allocations & dealloactions. On the compiler benchmark, this leads to some 2600 collections, which seems like a lot. (I have no idea why it seems like a lot, but it does.) I experimented with a policy that runs the collected every N deallocations (not counting deallocations the occur during a collection). I set N == 1000 and got 1600 collections on the compiler benchmark. There is only a small speedup (just a few percent), so maybe this change doesn't have a big effect. I don't recall much about the cost/complexity of various GC approaches. Jeremy

On Fri, Jun 30, 2000 at 04:57:44PM -0400, Jeremy Hylton wrote:
I've got two last minute questions.
Does it look to you like I checked in all of the changes that you and Vladimir discussed?
Nope. Neil Index: 0.13/Include/objimpl.h *** 0.13/Include/objimpl.h Fri, 30 Jun 2000 13:05:40 -0600 nas (python/o/19_objimpl.h 1.1.2.1.2.1.2.1 644) --- 0.13(w)/Include/objimpl.h Fri, 30 Jun 2000 15:09:51 -0600 nas (python/o/19_objimpl.h 1.1.2.1.2.1.2.1 644) *************** *** 204,209 **** --- 204,211 ---- (PyVarObject *) PyObject_MALLOC( _PyObject_VAR_SIZE((typeobj),(n)) ),\ (typeobj), (n)) ) + #define PyObject_DEL(op) PyObject_FREE(op) + /* This example code implements an object constructor with a custom allocator, where PyObject_New is inlined, and shows the important distinction between two steps (at least): *************** *** 242,248 **** PyObject_{New, VarNew, Del} to manage the memory. Set the type flag Py_TPFLAGS_GC and define the type method tp_recurse. You should also add the method tp_clear if your object is mutable. Include ! PyGC_INFO_SIZE in the calculation of tp_basicsize. Call PyObject_GC_Init after the pointers followed by tp_recurse become valid (usually just before returning the object from the allocation method. Call PyObject_GC_Fini before those pointers become invalid --- 244,250 ---- PyObject_{New, VarNew, Del} to manage the memory. Set the type flag Py_TPFLAGS_GC and define the type method tp_recurse. You should also add the method tp_clear if your object is mutable. Include ! PyGC_HEAD_SIZE in the calculation of tp_basicsize. Call PyObject_GC_Init after the pointers followed by tp_recurse become valid (usually just before returning the object from the allocation method. Call PyObject_GC_Fini before those pointers become invalid *************** *** 255,261 **** #define PyObject_GC_Fini(op) #define PyObject_AS_GC(op) (op) #define PyObject_FROM_GC(op) (op) - #define PyObject_DEL(op) PyObject_FREE(op) #else --- 257,262 ---- *************** *** 289,295 **** /* Get the object given the PyGC_Head */ #define PyObject_FROM_GC(g) ((PyObject *)(((PyGC_Head *)g)+1)) ! #define PyObject_DEL(op) PyObject_FREE( PyObject_IS_GC(op) ? \ (ANY *)PyObject_AS_GC(op) : \ (ANY *)(op) ) --- 290,297 ---- /* Get the object given the PyGC_Head */ #define PyObject_FROM_GC(g) ((PyObject *)(((PyGC_Head *)g)+1)) ! #undef PyObject_DEL ! #define PyObject_DEL(op) PyObject_FREE( (op && PyObject_IS_GC(op)) ? \ (ANY *)PyObject_AS_GC(op) : \ (ANY *)(op) ) Index: 0.13/Objects/object.c *** 0.13/Objects/object.c Fri, 30 Jun 2000 13:05:40 -0600 nas (python/E/29_object.c 1.1.1.1.1.1.1.1.1.1.1.1 644) --- 0.13(w)/Objects/object.c Fri, 30 Jun 2000 15:05:26 -0600 nas (python/E/29_object.c 1.1.1.1.1.1.1.1.1.1.1.1 644) *************** *** 192,205 **** PyObject *op; { #ifdef WITH_CYCLE_GC ! if (PyType_IS_GC(op->ob_type)) { ! PyGC_Head *g = PyObject_AS_GC(op); ! PyObject_FREE(g); ! } else ! #endif ! { ! PyObject_FREE(op); } } #ifndef WITH_CYCLE_GC --- 192,202 ---- PyObject *op; { #ifdef WITH_CYCLE_GC ! if (op && PyType_IS_GC(op->ob_type)) { ! op = (PyObject *) PyObject_AS_GC(op); } + #endif + PyObject_FREE(op); } #ifndef WITH_CYCLE_GC
participants (2)
-
Jeremy Hylton
-
Neil Schemenauer