Hi Franck, The __del__ method of all OCC wrapped object is overloaded. Object deletion management is delegated to the GarbageCollector class: all deleted objects are added to the GarbageCollector.garbage._collected_objects list (that's why you actually don't see any decref in your sample):
Python 2.6.1 (r261:67515, Jul 7 2009, 23:51:51) [GCC 4.2.1 (Apple Inc. build 5646)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> from OCC.Standard import * >>> GarbageCollector.garbage._collected_objects [] >>> s = Standard_Transient() >>> del s >>> GarbageCollector.garbage._collected_objects [<OCC.Standard.Standard_Transient; proxy of <Swig Object of type 'Standard_Transient *' at 0x1004b9c90> >] >>> I've been currently working on the GarbageCollector module. I definitely have to write a document about the way OCC/python/SWIG handle memory management. Thomas 2010/2/18 Frank Conradie <fr...@qfin.net> > Sorry Thomas, but _kill_pointed does not solve the issue. It looks like > the SWIG wrapper objects are not DECREF'd at all - see the example below, > which shows that calling "del" on a shape does not decrease the ref count of > the SWIG wrapper object at all: > > import gc > import sys > > import gc > from OCC.gp import * > from OCC.BRepPrimAPI import * > from OCC.TopExp import * > from OCC.TopoDS import * > > > w = 0.1 > fp1 = (0.,0.,0.) > fp2 = (w,w,w) > mkbox = BRepPrimAPI_MakeBox(gp_Pnt(fp1[0],fp1[1],fp1[2]), > gp_Pnt(fp2[0],fp2[1],fp2[2])) > s = mkbox.Shell() > > > class MemTest(object): > pass > mem = MemTest() > > # The next 3 lines show that _kill_pointed nullifies the underlying shape > print 'before: IsNull=', s.IsNull() > s._kill_pointed() > print 'after: IsNull=', s.IsNull() > > print gc.get_count() > print gc.collect() > print gc.get_count() > for o in gc.get_objects(): > if isinstance(o, TopoDS_Shape) or isinstance(o, MemTest): > print type(o), sys.getrefcount(o) > > # The next 2 lines should remove s and mem from gc.get_objects, but it only > removes mem!!! > del s > del mem > > print gc.get_count() > print gc.collect() > print gc.get_count() > for o in gc.get_objects(): > if isinstance(o, TopoDS_Shape) or isinstance(o, MemTest): > print type(o), sys.getrefcount(o) > > > I'm not sure where to go from here. > - Frank > > > > On 17/02/2010 8:29 PM, Thomas Paviot wrote: > > 2010/2/18 Frank Conradie <fr...@qfin.net> > >> Hi guys, >> > > Hi Franck, > > >> >> After running into serious memory use issues with our geometric >> processing algorithm, I have done a simple experiment that seems to show >> that wrapper garbage collection does not work at all. Try the code >> below, and you should run out of memory in no time: >> >> >> import gc >> from OCC.gp import * >> from OCC.BRepPrimAPI import * >> from OCC.TopExp import * >> >> def TestMemory(): >> w = 0.1 >> fp1 = (0.,0.,0.) >> fp2 = (w,w,w) >> mkbox = BRepPrimAPI_MakeBox(gp_Pnt(fp1[0],fp1[1],fp1[2]), >> gp_Pnt(fp2[0],fp2[1],fp2[2])) >> s1 = mkbox.Shell() >> e = TopExp_Explorer() >> for i in range(1000000): >> print i >> e.Init(s1, TopAbs_FACE) >> while e.More(): >> sh = e.Current() >> e.Next() >> if not (i % 1000): >> print 'Collecting garbage...' >> gc.collect() >> while 1: >> pass >> >> >> Not sure if this is a known issue or not, > > > It's known to be an issue, see: > * http://www.opencascade.org/org/forum/thread_17702/ > * the changelog of the 0.4 release > > >> but it certainly makes the >> wrapper problematic for our current purposes. If you can point me at the >> right place in the wrapper generator I can maybe try and help. >> > > The standard python gc module can not be used with pythonOCC: it's > perfectly suitable to manage python objects deletion, but fails to properly > handle the C++ pointed objects. A GarbageCollector class is available from > any pythonOCC module you're using. For instance: > > Python 2.6.1 (r261:67515, Jul 7 2009, 23:51:51) > [GCC 4.2.1 (Apple Inc. build 5646)] on darwin > Type "help", "copyright", "credits" or "license" for more information. > >>> from OCC.Standard import * > >>> GarbageCollector > <module 'OCC.GarbageCollector' from > '/Library/Python/2.6/site-packages/OCC/GarbageCollector.pyc'> > >>> dir(GarbageCollector) > ['GarbageCollector', '__builtins__', '__doc__', '__file__', '__name__', > '__package__', 'garbage', 'sys'] > >>> GarbageCollector.garbage > <OCC.GarbageCollector.GarbageCollector object at 0x100593e10> > >>> dir(GarbageCollector.garbage) > ['__class__', '__delattr__', '__dict__', '__doc__', '__format__', > '__getattribute__', '__hash__', '__init__', '__module__', '__new__', > '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', > '__str__', '__subclasshook__', '__weakref__', '_collected_objects', > 'collect_object', 'get_collected', 'purge'] > > The source code of this module is here: > > http://svn.gna.org/viewcvs/pythonocc/trunk/src/wrapper/GarbageCollector.py?rev=706&view=markup > > In a few words, if you want to completely free memory: > GarbageCollector.garbage.purge() > > If you want to free one specific object, use the _kill_pointed() method > of that object (Nulify, Clear, Destroy won't work). > > I'll take time to write a more detailed message tomorrow about that > topic. > > >> Thanks, >> Frank Conradie >> Qfinsoft >> > > All the best, > > Thomas > > > _______________________________________________ > Pythonocc-users mailing list > pythonocc-us...@gna.orghttps://mail.gna.org/listinfo/pythonocc-users > > > _______________________________________________ > Pythonocc-users mailing list > Pythonocc-users@gna.org > https://mail.gna.org/listinfo/pythonocc-users > >
_______________________________________________ Pythonocc-users mailing list Pythonocc-users@gna.org https://mail.gna.org/listinfo/pythonocc-users