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

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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
牙科就诊管理系统利用当下成熟完善的SSM框架,使用跨平台的可开发大型商业网站的Java语言,以及最受欢迎的RDBMS应用软件之一的Mysql数据库进行程序开发。实现了用户在线查看数据。管理员管理病例管理、字典管理、公告管理、药单管理、药品管理、药品收藏管理、药品评价管理、药品订单管理、牙医管理、牙医收藏管理、牙医评价管理、牙医挂号管理、用户管理、管理员管理等功能。牙科就诊管理系统的开发根据操作人员需要设计的界面简洁美观,在功能模块布局上跟同类型网站保持一致,程序在实现基本要求功能时,也为数据信息面临的安全问题提供了一些实用的解决方案。可以说该程序在帮助管理者高效率地处理工作事务的同时,也实现了数据信息的整体化,规范化与自动化。 管理员在后台主要管理病例管理、字典管理、公告管理、药单管理、药品管理、药品收藏管理、药品评价管理、药品订单管理、牙医管理、牙医收藏管理、牙医评价管理、牙医挂号管理、用户管理、管理员管理等。 牙医列表页面,此页面提供给管理员的功能有:查看牙医、新增牙医、修改牙医、删除牙医等。公告信息管理页面提供的功能操作有:新增公告,修改公告,删除公告操作。公告类型管理页面显示所有公告类型,在此页面既可以让管理员添加新的公告信息类型,也能对已有的公告类型信息执行编辑更新,失效的公告类型信息也能让管理员快速删除。药品管理页面,此页面提供给管理员的功能有:新增药品,修改药品,删除药品。药品类型管理页面,此页面提供给管理员的功能有:新增药品类型,修改药品类型,删除药品类型。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值