Can I possibly free ALL the memory?

pacquets at newsguy.com pacquets at newsguy.com
Fri May 16 21:51:44 EDT 2003


I've been using the Reduced Python (based on 1.5.2) on SourceForge (which was
originally for PalmOS).  I want to embed it in our product, which is a device
that doesn't have a "real" OS.  ('Nuff said about that!)  I've been using Purify
on NT to get the memory bugs out, and making good progress with that.

Anyhow, I need for this thing to be serially reusable, as well as reentrant, and
I want every single byte of malloc'ed memory to go away after Py_Finalize()
runs.  (In case you haven't noticed, it doesn't, normally).

I now have it down to two nodes, of 1536 and 96 bytes, both of which come from
dictresize.  Listed below are all the things I'm doing - what else can I do to
get these last two out?  (I SUSPECT they come from __builtins__, ultimately, but
I'm not positive about that.)   And why isn't what I'm doing freeing them
already?

1) I've got Py_TRACE_REFS and Py_REF_DEBUG turned on.

2) I have a sys.exitfunc like this:

def freeAll():
	import sys
	for modname in sys.modules.keys():
		if modname != 'sys':
			x = sys.modules[modname];
			d = x.__dict__
			for objname in d.keys():
				del d[objname]
	sys.flushall()

3) then, in C, I have this:

	PyObject *opCur, *opNext;
	int		ct=0;

	PyString_Clean();
	/* (gets rid of interned strings) */
	/* the algorithm, screwy as it might seem, is to deallocate
		everything "properly" (according to its type destructor).
		But be sure not to get into an infinite loop, so don't
		go through any more times than there are objects!  When
		done, we'll kill whatever's left the old fashioned way.

	*/
	while (refchain._ob_next != &refchain) {
		ct++;
		if (ct >= saveTotalObjects) break;
		opCur = refchain._ob_next;
		if (!PyObj_IsPoolInteger(opCur) &&
			!PyObj_IsPoolFloat(opCur)) {
			_Py_Dealloc(opCur);
		}
	}
	for (opCur = refchain._ob_next; opCur != &refchain; ) {
		ct++;
		opNext = opCur->_ob_next;
		if (!PyObj_IsPoolInteger(opCur) &&
			!PyObj_IsPoolFloat(opCur)) {
			PyMem_Free(opCur);
		}
		opCur = opNext;
	}


	/* from here on, it's mostly setting globals to NULL.  The things
	 * that the globals pointed to should be already gone.
	 * */
	_PyImport_Clean();
	PyFrame_Clean();
	PyDict_Clean();
	PyList_Clean();
	PyPosix_Clean();
	PyMethod_Clean();
	builtin_Clean();
	PyInt_KillBlockList();   /* this gets rid of small_ints & block_list */
	PyFloat_KillBlockList();
}





More information about the Python-list mailing list