zoukankan      html  css  js  c++  java
  • Away3D 的实体收集器Bug

    最近在改Away3D源码的时候遇到个很郁闷的问题,发现创建的Mesh 释放不掉。

    分析源码发现 EntityListItemPool 类中逻辑Bug在getItem()函数中发现_poolSize 对象池大小如果够用的情况下 它采用的方式是复用EntityListItem

    那么假设我删除了场景上有10个对象我全部删除了然后我再创建9个 这时候总有1个对象是被缓存着的。一直要等到我创建第10个对象他才会被释放掉。

    没辙了跑到 看看对象销毁流程吧。

    对象被销毁时会调用 Scene3D 的 unregisterEntity函数,这个函数只是删除了Scene3D 和 显示对象的引用。但是EntityListItemPool中还是存在实例引用

     看了看收集器 每次都要经过 Scene3D 的 traversePartitions函数。

    那我先在unregisterEntity函数调用的时候做一次记录把要删除的显示对象添加到一个列表中。

    private var _unregisterEntityList:Vector.<Entity> = new Vector.<Entity>;
      /**
       * When an entity is removed from the scene, or from one of its children, remove it from its former partition tree.
       * @private
       */
      arcane function unregisterEntity(entity : Entity) : void
      {
       _unregisterEntityList.push(entity);
       entity.implicitPartition.removeEntity(entity);   
      }

    这样在下一帧执行渲染的时候我就知道要释放掉哪些对象了。然后修改traversePartitions函数.

    public function traversePartitions(traverser : PartitionTraverser) : void
      {
       var i : uint;
       var len : uint = _partitions.length;
       if(traverser is EntityCollector)
       {
        while(_unregisterEntityList.length)
        {
         var _entity:Entity = _unregisterEntityList.shift();
         (traverser as EntityCollector).entityListItemPool.unmap(_entity);
         (traverser as EntityCollector).renderableListItemPool.unmap(_entity);
        }
       }
       traverser.scene = this;

       while (i < len)
        _partitions[i++].traverse(traverser);
      }

    每次在新的一轮收集前把上一帧要清楚掉的对象全部干掉。

    然后跑到entityListItemPool 类里添加一段代码:

    public function unmap(mesh:Entity) : void
      {
       var _mesh:Mesh = mesh as Mesh;
       for(var j:int =0;j<_mesh.numSubMesh;j++)
       {
        for(var i:int = 0; i < _pool.length; i++)
        {
         if((_pool[i].renderable is SubMesh) && (_pool[i].renderable as SubMesh).parentMesh && (_pool[i].renderable as SubMesh).parentMesh == _mesh)
         {
          (_pool[i].renderable as SubMesh).parentMesh = null;
          _pool.splice(i,1);
          _poolSize --;
          continue;
         }
        }
       }
      }

    这样保证了对象的释放。OK 这下好了

    测试下了一下没有问题全部乖乖的垃圾回收了。

  • 相关阅读:
    chrome浏览器中安装以及使用Elasticsearch head 插件
    windows10 升级并安装配置 jmeter5.3
    linux下部署Elasticsearch6.8.1版本的集群
    【Rollo的Python之路】Python 爬虫系统学习 (八) logging模块的使用
    【Rollo的Python之路】Python 爬虫系统学习 (七) Scrapy初识
    【Rollo的Python之路】Python 爬虫系统学习 (六) Selenium 模拟登录
    【Rollo的Python之路】Python 爬虫系统学习 (五) Selenium
    【Rollo的Python之路】Python 爬虫系统学习 (四) XPath学习
    【Rollo的Python之路】Python 爬虫系统学习 (三)
    【Rollo的Python之路】Python sys argv[] 函数用法笔记
  • 原文地址:https://www.cnblogs.com/ch06src/p/3874428.html
Copyright © 2011-2022 走看看