javascript - 我的 PyV8 上下文泄漏内存

标签 javascript memory-leaks garbage-collection v8 pyv8

无论我尝试使用 PyV8,我总是会遇到大量内存泄漏。即使使用空字符串执行 evals,它似乎仍然会以某种方式泄漏内存。在下面发布的示例中,使用空字符串执行 1000 万次 eval 会生成 320MB 内存,之后显式调用垃圾收集器时仅收集 20MB 内存。上下文是否可达或不再可达对我来说似乎没有什么区别。我已经用类似的测试测试了我的 python 本身,它不会泄漏内存。我做错了什么吗?

版本

PyV8 修订版 557,使用 PyV8 的 setup.py 在同一台计算机上构建

V8 修订版 19632,使用 PyV8 的 setup.py 在同一台机器上构建

操作系统:Ubuntu 12.04

测试代码

import unittest, gc, os, logging as python_logging
from PyV8 import JSEngine, JSContext

_proc_status = '/proc/%d/status' % os.getpid()
_scale = {'kB': 1024.0, 'mB': 1024.0*1024.0,
          'KB': 1024.0, 'MB': 1024.0*1024.0}

def log_memory_usage(intro_text=""):
    python_logging.info(
        (
            '%s process %d now uses %.1f MB resident'
                %(intro_text, os.getpid(), resident()/(1024*1024))
        ).strip()
    )

def _VmB(VmKey):
    '''Private.
    '''
    global _proc_status, _scale
     # get pseudo file  /proc/<pid>/status
    try:
        t = open(_proc_status)
        v = t.read()
        t.close()
    except:
        return 0.0  # non-Linux?
     # get VmKey line e.g. 'VmRSS:  9999  kB\n ...'
    i = v.index(VmKey)
    v = v[i:].split(None, 3)  # whitespace
    if len(v) < 3:
        return 0.0  # invalid format?
     # convert Vm value to bytes
    return float(v[1]) * _scale[v[2]]

def resident(since=0.0):
    '''Return resident memory usage in bytes.
    '''
    return _VmB('VmRSS:') - since   

class TestMemoryWithJSContext(unittest.TestCase):
  def test_python_memory_management(self):
    def inner():
        with JSContext() as ctx:
            log_memory_usage("before empty evals")
            for index1 in range(1000):
                for index2 in range(10000):
                    ctx.eval("")
            log_memory_usage("after empty evals")
            JSEngine.collect()
    log_memory_usage("before JSContext memory tests")
    inner()
    JSEngine.collect()
    gc.collect()
    JSEngine.collect()
    gc.collect()
    log_memory_usage("after JSContext memory tests and gc")
    print "Py gc.garbage:", gc.garbage

class CardEngineTestSuite(unittest.TestSuite):
    def __init__(self):
        super(CardEngineTestSuite, self).__init__()
        self.addTests(unittest.TestLoader().loadTestsFromTestCase(TestPython))
        self.addTests(unittest.TestLoader().loadTestsFromTestCase(TestMemoryWithJSContext))

if __name__ == '__main__':
    python_logging.basicConfig(level=python_logging.INFO, format='%(asctime)s %(message)s')
    unittest.TextTestRunner().run(CardEngineTestSuite())
    unittest.TextTestRunner().run(CardEngineTestSuite())
    python_logging.info(str(gc.garbage))

输出

.2014-03-28 21:41:34,198 before JSContext memory tests process 110 now uses 14.1 MB resident
2014-03-28 21:41:34,199 before empty evals process 110 now uses 14.4 MB resident
2014-03-28 21:41:55,513 after empty evals process 110 now uses 348.8 MB resident
2014-03-28 21:41:56,926 after JSContext memory tests and gc process 110 now uses 322.3 MB resident
Py gc.garbage: []
.
----------------------------------------------------------------------
Ran 2 tests in 26.838s

OK
.2014-03-28 21:42:01,103 before JSContext memory tests process 110 now uses 322.5 MB resident
2014-03-28 21:42:01,104 before empty evals process 110 now uses 322.5 MB resident
2014-03-28 21:42:25,714 after empty evals process 110 now uses 636.5 MB resident
2014-03-28 21:42:28,459 after JSContext memory tests and gc process 110 now uses 629.3 MB resident
Py gc.garbage: []
.
----------------------------------------------------------------------
Ran 2 tests in 31.532s

OK

最佳答案

下面的 PyV8 票证中描述的答案为我解决了这个问题 - 尽管垃圾收集现在占用了大量的 CPU 时间。为了解决这个问题,我将 PyV8 代码移至 celery Worker 中,并让它在后台进行垃圾收集。如果您想查看代码,请告诉我,现在我真的没有时间准备示例代码。

https://code.google.com/p/pyv8/issues/detail?id=229&sort=-id

关于javascript - 我的 PyV8 上下文泄漏内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22726593/

相关文章:

Javascript : Show content of select element on focus on tab key navigation

javascript - 使用jquery更改具有属性值的相应节点的文本

C++ - 内存泄漏 : where is the pointer (meta) information stored?

Java Netty : memory leak problem with DefaultChannelHandlerContext

java - tomcat7 服务器 java 中加载的类、cpu 和线程的峰值

java - 如何处理 Java 中较长的 Full Garbage Collection 周期

javascript - 当我上传文件后尝试读取事件目标时,事件目标返回为空

Javascript 逻辑运算符 :?

c - zlib inflateReset 导致内存泄漏(不是)

java - 限制JVM不调用GC