OK, so just what determines Zope's memory usage? I naively assumed that beyond a certain minimum size it would be the object cache. But my zope process seems to just keep growing. If I go to the' database management page and flush the cache, the size doesn't change. I need to understand at least a little bit more about the memory profile, because the Zope process is periodicaly consuming all available swap space and I have to restart it. I'm sure the fact that I'm touching a lot of objects in the database (a couple thousand) is part of the problem, but I'm doing it in batches of 250, so I would think Zope's memory management could handle that. On a possibly related issue, I turned on the stupid file logger, but now I occasionally get an error page with the following traceback: Error Type: TypeError Error Value: call of non-function (type file) <!-- Traceback (innermost last): File ...Zope-2.1.2-src/lib/python/ZPublisher/Publish.py, line 214, in publish_module File ...Zope-2.1.2-src/lib/python/ZPublisher/Publish.py, line 179, in publish File ...Zope-2.1.2-src/lib/python/Zope/__init__.py, line 202, in zpublisher_exception_hook (Object: ElementWithAttributes) File ...Zope-2.1.2-src/lib/python/ZPublisher/Publish.py, line 165, in publish File ...Zope-2.1.2-src/lib/python/ZPublisher/mapply.py, line 160, in mapply (Object: reindex_database) File ...Zope-2.1.2-src/lib/python/ZPublisher/Publish.py, line 102, in call_object (Object: reindex_database) File ...Zope-2.1.2-src/lib/python/OFS/DTMLMethod.py, line 145, in __call__ (Object: reindex_database) File ...Zope-2.1.2-src/lib/python/DocumentTemplate/DT_String.py, line 502, in __call__ (Object: reindex_database) File ...Zope-2.1.2-src/lib/python/DocumentTemplate/DT_In.py, line 611, in renderwb (Object: Catalog) File ...Zope-2.1.2-src/lib/python/DocumentTemplate/DT_Let.py, line 145, in render (Object: objid=id) File ...Zope-2.1.2-src/lib/python/DocumentTemplate/DT_With.py, line 148, in render (Object: getobject(data_record_id_)) File /usr/local/src/zope/Zope-2.1.2-src/lib/python/Products/ZCatalog/CatalogAwareness.py, line 191, in reindex_object (Object: CatalogAware) File /usr/local/src/zope/Zope-2.1.2-src/lib/python/Products/ZCatalog/CatalogAwareness.py, line 181, in index_object (Object: CatalogAware) File ...Zope-2.1.2-src/lib/python/Products/ZCatalog/ZCatalog.py, line 344, in catalog_object (Object: ElementWithAttributes) File ...Zope-2.1.2-src/lib/python/Products/ZCatalog/Catalog.py, line 356, in catalogObject File ...Zope-2.1.2-src/lib/python/SearchIndex/UnTextIndex.py, line 243, in index_object File ...Zope-2.1.2-src/lib/python/SearchIndex/Lexicon.py, line 129, in set File ...Zope-2.1.2-src/lib/python/ZODB/Connection.py, line 409, in setstate File ...Zope-2.1.2-src/lib/python/zLOG.py, line 198, in LOG File ...Zope-2.1.2-src/lib/python/Zope/ZLogger/ZLogger.py, line 18, in log_write File ...Zope-2.1.2-src/lib/python/Zope/ZLogger/stupidFileLogger.py, line 40, in __call__ File ...Zope-2.1.2-src/lib/python/Zope/ZLogger/stupidFileLogger.py, line 99, in stupid_log_write TypeError: (see above)
"R. David Murray" wrote:
OK, so just what determines Zope's memory usage? I naively assumed that beyond a certain minimum size it would be the object cache.
Also the database index. This grows a small amount for each object in the database. This is stored entirly in memory.
But my zope process seems to just keep growing. If I go to the' database management page and flush the cache, the size doesn't change.
The I would suspect a memory leak, or circular references. A memory leak means simply that some part of your application is allocating memory and not releasing it. This typically happens in C. Suspect are the Zope core components themselves (possible), any third party database adapters you use (likely), or a core python module (not likely). Circular refs are a common mistake in python. Python works on a ref counting system. When the number of references to an object drops to 1 in Zope, then the object is deactivated and written to disk (if it changed). Why 1? Well, when the ref count is one then that means only one object reffers to your object, and that object *should* be the object cache itself. When the cache sees that an object has only only reference, it knows that that reference is itself and it can deactivate the object. If you have another object A, that refers to B, and B refers to A, then both will have a ref count of 2 and neither object will ever get deactivated. Over time if a lot of these pairs of objects come about then you will run out of memory and flushing the cache will do you no good (because according to the cache they are not unreferenced).
I need to understand at least a little bit more about the memory profile, because the Zope process is periodicaly consuming all available swap space and I have to restart it.
Look at Control_Panel/manage_debug. This shows you the refcounts for all objects. Track these values over the course of running Zope and see if any of them go up and never down. You'll get the idea.
I'm sure the fact that I'm touching a lot of objects in the database (a couple thousand) is part of the problem, but I'm doing it in batches of 250, so I would think Zope's memory management could handle that.
Yes it shouldn't be a problem.
On a possibly related issue, I turned on the stupid file logger, but now I occasionally get an error page with the following traceback:
Error Type: TypeError Error Value: call of non-function (type file)
<!-- Traceback (innermost last): File ...Zope-2.1.2-src/lib/python/Zope/ZLogger/stupidFileLogger.py, line 99, in stupid_log_write TypeError: (see above)
Hmmmm... that's not normal. Line 99 is a call to _stupid_dest.write, how is _stupid_dest.write getting assigned a file object? I know your asking _us_ that, but I personaly have no idea. Perhaps you could track it down a bit further given that information. -Michel
Just another data point: I too frequently get this same error when debugging ZScheduler. It seems to be triggered by some other error; but I haven't succeeded in tracking it down, even after much tracing. -- Loren
"R. David Murray" wrote:
{snip]
On a possibly related issue, I turned on the stupid file logger, but now I occasionally get an error page with the following traceback:
Error Type: TypeError Error Value: call of non-function (type file)
<!-- Traceback (innermost last): File ...Zope-2.1.2-src/lib/python/Zope/ZLogger/stupidFileLogger.py, line 99, in stupid_log_write TypeError: (see above)
Hmmmm... that's not normal. Line 99 is a call to _stupid_dest.write, how is _stupid_dest.write getting assigned a file object?
I know your asking _us_ that, but I personaly have no idea. Perhaps you could track it down a bit further given that information.
-Michel
_______________________________________________ Zope-Dev maillist - Zope-Dev@zope.org http://lists.zope.org/mailman/listinfo/zope-dev ** No cross posts or HTML encoding! ** (Related lists - http://lists.zope.org/mailman/listinfo/zope-announce http://lists.zope.org/mailman/listinfo/zope )
Loren Stafford wrote:
Just another data point: I too frequently get this same error when debugging ZScheduler. It seems to be triggered by some other error; but I haven't succeeded in tracking it down, even after much tracing.
-- Loren
Found it, I didn't see it before because it's fixed in the CVS. Line 97 and 99 of lib/python/Zope/ZLogger/stupidFileLogger.py should __stupid_dest.write(), not _stupid_dest(): try: _stupid_dest.write(format_exception( error[0], error[1], error[2], trailer='\n', limit=100)) except: _stupid_dest.write("%s: %s\n" % error[:2]) The difference being that '.write' is inserted. Simple typo. -Michel
participants (3)
-
Loren Stafford -
Michel Pelletier -
R. David Murray