博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Away3D 的实体收集器Bug
阅读量:6956 次
发布时间:2019-06-27

本文共 1851 字,大约阅读时间需要 6 分钟。

最近在改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 这下好了

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

转载于:https://www.cnblogs.com/ch06src/p/3874428.html

你可能感兴趣的文章
Linux使用du和df查看磁盘和文件夹占用空间
查看>>
CentOS 6.6 MySQL install
查看>>
从零开始用gulp
查看>>
android之Activity的生命周期
查看>>
hadoop2.4 支持snappy
查看>>
STL 笔记(四) 迭代器 iterator
查看>>
2017"百度之星"程序设计大赛 - 复赛1003&&HDU 6146 Pokémon GO【数学,递推,dp】
查看>>
[LeetCode] Valid Parenthesis String 验证括号字符串
查看>>
各大SRC中的CSRF技巧
查看>>
Docker for Windows 使用入门
查看>>
【Django】Web应用开发经由
查看>>
SpringBoot(九)-- SpringBoot JDBC
查看>>
Spring + Mybatis - 原始dao开发整合 与 Mapper代理整合
查看>>
基于Centos搭建nginx+uwsgi运行django环境
查看>>
context switch
查看>>
Oracle awr报告生成操作步骤
查看>>
【DB2】DB2使用IMPORT命令导入含有自增长列的表报错处理
查看>>
微服务之springCloud-docker-comsumer(三)
查看>>
dhcpcd守护进程分析【转】
查看>>
Linux - 理不清的权限chmod与chown区别
查看>>