[Zope3-checkins] CVS: Zope3/src/zodb - connection.py:1.19 serialize.py:1.16

Jeremy Hylton jeremy@zope.com
Mon, 17 Mar 2003 12:09:41 -0500


Update of /cvs-repository/Zope3/src/zodb
In directory cvs.zope.org:/tmp/cvs-serv30495/src/zodb

Modified Files:
	connection.py serialize.py 
Log Message:
Fix vast memory leak in object pickling.

There was a cycle between the ObjectWriter and its Pickler, which was
not collected because the Pickler does not participate in GC.  Add a
close() method that releases references to the Pickler.


=== Zope3/src/zodb/connection.py 1.18 => 1.19 ===
--- Zope3/src/zodb/connection.py:1.18	Thu Mar 13 17:11:34 2003
+++ Zope3/src/zodb/connection.py	Mon Mar 17 12:09:41 2003
@@ -454,6 +454,7 @@
         writer = ObjectWriter(self)
         for obj in writer.newObjects(object):
             self._commit_store(writer, obj, transaction)
+        writer.close()
 
     def _commit_store(self, writer, pobject, transaction):
         oid = pobject._p_oid


=== Zope3/src/zodb/serialize.py 1.15 => 1.16 ===
--- Zope3/src/zodb/serialize.py:1.15	Thu Mar 13 16:32:27 2003
+++ Zope3/src/zodb/serialize.py	Mon Mar 17 12:09:41 2003
@@ -96,6 +96,16 @@
 _marker = object()
 
 class ObjectWriter:
+    """Serializes objects for storage in the database.
+
+    The ObjectWriter creates object pickles in the ZODB format.  It
+    also detects new persistent objects reachable from the current
+    object.
+
+    The client is responsible for calling the close() method to avoid
+    leaking memory.  The ObjectWriter uses a Pickler internally, and
+    Pickler objects do not participate in garbage collection.
+    """
 
     def __init__(self, jar=None):
         self._file = StringIO()
@@ -105,6 +115,11 @@
         if jar is not None:
             assert hasattr(jar, "newObjectId")
         self._jar = jar
+
+    def close(self):
+        # Explicitly break cycle involving pickler
+        self._p.persistent_id = None
+        self._p = None
 
     def _persistent_id(self, obj):
         """Test if an object is persistent, returning an oid if it is.