Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

python object is not garbage collected when it's in a javascript closure #186

Open
GoogleCodeExporter opened this issue May 2, 2015 · 7 comments

Comments

@GoogleCodeExporter
Copy link

What steps will reproduce the problem?

Run the following code (also attached):

import gc
import sys
import inspect
import weakref

import PyV8


class PyObj(object):
    def __init__(self):
        pass

class Global(object):
    def Obj(self):
        return PyObj()

    def out(self, v):
        print "-- Script out: %s --" % (v,)


tracks = []
def obj_gone(ref):
    print "**Obj deleted**"
def track_obj(obj):
    tracks.append(weakref.ref(obj, obj_gone))


def run_case(name, js):
    print "Case %s:" % (name,)
    ctxt = PyV8.JSContext(Global())
    with ctxt:
        obj = ctxt.eval(js)
        track_obj(obj)

        print "refcount:", sys.getrefcount(obj)
        print "V8 theObj=null"
        ctxt.eval("theObj = null;")
        print "Py obj=None"
        obj = None
        print "V8 gc"
        PyV8.JSEngine.collect()
        print "Py gc"
        gc.collect()
        print "Py gc.garbage:", gc.garbage
    print


gc.set_debug(gc.DEBUG_COLLECTABLE | gc.DEBUG_UNCOLLECTABLE |
             gc.DEBUG_INSTANCES | gc.DEBUG_OBJECTS)

run_case("one", """
    function tighty() {
        var localObj = Obj();
        localObj.foobar = function () {
            out("hi" + this);
        };
        return localObj;
    }
    var theObj = tighty();
    theObj.foobar();
    theObj;""")

run_case("two", """
    function tighty() {
        var localObj = Obj();
        localObj.foobar = function () {
            out("hi" + localObj);
        };
        return localObj;
    }
    var theObj = tighty();
    theObj.foobar();
    theObj;""")


What is the expected output? What do you see instead?

I expect the object to get deleted in both cases, that is:

-- Script out: hi[object Object] --
refcount: 3
V8 theObj=null
Py obj=None
V8 gc
**Obj deleted**
Py gc
Py gc.garbage: []

However, in the second case, the object is never deleted:

Case two:
-- Script out: hi[object Object] --
refcount: 3
V8 theObj=null
Py obj=None
V8 gc
Py gc
Py gc.garbage: []

What version of the product are you using? On what operating system?

Python 2.6.6 with PyV8-1.0-preview-r443.win32-py2.6.exe on Windows 7

Please provide any additional information below.

Seems to be an issue with how V8's garbage collector interacts w/ Python 
objects within closures... it seems to not release its reference counts even 
though it's no longer accessible from anywhere. 

Original issue reported on code.google.com by [email protected] on 17 Jul 2013 at 7:29

Attachments:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant