首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何正确地释放和释放用于V8.Net.V8Engine实例的内存?

如何正确地释放和释放用于V8.Net.V8Engine实例的内存?
EN

Stack Overflow用户
提问于 2015-12-07 13:22:35
回答 1查看 405关注 0票数 1

当我使用我的V8Engine实例时,我遇到了一个问题,它似乎有一个小内存泄漏,并且处理它,以及强制垃圾收集似乎没有多大帮助。它最终会在V8Enging local_m_negine = new V8Engine()上抛出一个Fatal error in heap setup, Allocation failed - process out of memoryAttempted to read or write protected memory. This is often an indication that other memory is corrupt.

运行时通过任务管理器监视程序的内存使用情况,确认它正在泄漏内存,我认为每隔几秒钟大约有1000 KB。我怀疑它是在未被收集的执行脚本中声明的变量,或者与GlobalObject.SetProperty方法有关。调用V8Engine.ForceV8GarbageCollection()V8Engine.Dispose()甚至GC.WaitForPendingFinalizers() & GC.Collect()并不能防止内存泄漏(尽管值得注意的是,在这些命令到位后,它的泄漏速度似乎要慢一些,而且我知道我不应该使用GC,但作为最后的手段,它是否能解决这个问题。)

还可能提供解决方案的一个切线问题是无法清除V8Engine的执行上下文。我被要求为每个脚本释放和重新实例化引擎,我认为这是内存泄漏发生的地方,否则我会遇到已经声明变量的问题,导致V8Engine.Execute()抛出这样的异常。

我可以肯定的是,内存泄漏与V8Engine实现有关,因为运行使用Microsoft.JScript的这个程序的旧版本没有这样的内存泄漏,并且使用的内存保持一致。

受影响的代码如下;

代码语言:javascript
复制
//Create the V8Engine and dispose when done
using (V8Engine local_m_engine = new V8Engine()) 
{
    //Set the Lookup instance as a global object so that the JS code in the V8.Net wrapper can access it
    local_m_engine.GlobalObject.SetProperty("Lookup", m_lookup, null, true, ScriptMemberSecurity.ReadOnly);
    //Execute the script
    result = local_m_engine.Execute(script);

    //Please just clear everything I can't cope.
    local_m_engine.ForceV8GarbageCollection();
    local_m_engine.GlobalObject.Dispose();
}

编辑:

不知道这有多有用,但我已经在上面运行了一些内存分析工具,并了解到在运行了独立版本的原始代码之后,我的软件最终得到了大量IndexedObjectList的空值实例(参见此处:http://imgur.com/a/bll5K)。对于创建的每个V8Engine实例,它似乎都有一个类的实例,但它们没有被释放或释放。我情不自禁地觉得好像这里漏掉了一个命令之类的东西。我用来测试和重新创建上述实现导致的内存泄漏的代码如下所示:

代码语言:javascript
复制
using System;
using V8.Net;

namespace V8DotNetMemoryTest
{
    class Program
    {
        static void Main(string[] args)
        {
            string script = @"  var math1 = 5;
                                var math2 = 10;
                                result = 5 + 10;";
            Handle result;
            int i = 0;
            V8Engine local_m_engine;
            while (true)
            {
                //Create the V8Engine and dispose when done
                local_m_engine = new V8Engine();

                //Set the Lookup instance as a global object so that the JS code in the V8.Net wrapper can access it
                //local_m_engine.GlobalObject.SetProperty("Lookup", m_lookup, null, true, ScriptMemberSecurity.ReadOnly);
                //Execute the script
                result = local_m_engine.Execute(script);
                Console.WriteLine(i++);

                result.ReleaseManagedObject();
                result.Dispose();

                local_m_engine.Dispose();
                GC.WaitForPendingFinalizers();
                GC.Collect();

                local_m_engine = null;

            }
        }
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-03-07 01:59:26

对不起,我不知道这个问题的存在。确保使用v8.net标记。

你的问题是这一行:

result = local_m_engine.Execute(script);

返回的结果永远不会被处理。)您负责返回的句柄。这些句柄是结构值,而不是类对象。

你也可以做using (result = local_m_engine.Execute(script)) { ... }

有一个新版本发布。我终于再次复活这个项目,因为我将需要它的FlowScript VPL项目-它现在支持.Net标准以及跨平台的支持!

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34134619

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档