• 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 这下好了

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

  • 相关阅读:
    【SAS NOTES】将文本转化为数据格式 input()
    【SAS NOTES】proc tabulate遇到的问题
    【SAS NOTES】proc sql
    【SAS NOTES】转载 sas函数&模块
    【SAS NOTE】substr字符串提取函数
    【SAS NOTES】输出结果到excel
    【SAS NOTES】脏数据
    【SAS NOTES】字符串处理函数
    【SAS NOTES】实际分析应用
    多项式的乘法满足结合律和交换律
  • 原文地址:https://www.cnblogs.com/ch06src/p/3874428.html
Copyright © 2020-2023  润新知