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

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

  • 相关阅读:
    启动tomcat时jmx port被占用
    Intellij Idea下tomcat设置自动编译
    IDEA的快捷键的使用
    IDEA2017注册码
    hosts文件路径及文件介绍
    关于JAVA开发工具IDEA使用
    如何用Word编辑参考文献------这是引用一位大师的
    TDK标签在SEO中的应用
    简单的线条不简单的画
    HTML--网页自动跳转 5种方法
  • 原文地址:https://www.cnblogs.com/ch06src/p/3874428.html
Copyright © 2011-2022 走看看