Hi Thomas

I think I can guess what is happening - in purge, when you set the _collected_objects list to empty, all the objects in the list go out of scope and are added back into the list (because their __del__ methods get called). Therefore the refcount of these objects will NEVER get down to zero.

- Frank

On 18/02/2010 2:06 PM, Thomas Paviot wrote:
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 <mailto: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 <mailto: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
    
<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-users@gna.org <mailto:Pythonocc-users@gna.org>
    https://mail.gna.org/listinfo/pythonocc-users

    _______________________________________________
    Pythonocc-users mailing list
    Pythonocc-users@gna.org <mailto: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
_______________________________________________
Pythonocc-users mailing list
Pythonocc-users@gna.org
https://mail.gna.org/listinfo/pythonocc-users

Reply via email to