Android OSG垃圾收集机制(DeleteHandler)
发布日期:2021-06-30 21:23:07 浏览次数:2 分类:技术文章

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

   C++中最通用的删除对象的方法是delete,OSG 的智能指针也是采用这种方式来释放对象的,不过由于OSG采用多线程更新/渲染的方式(这一点我们会在后面的日子中详细介绍),这样做可能带来会某些隐患,想象这样一种情况:

  1.     场景某个的节点负责显示某种图形,它的工作一直很正常;
  2.     我们采用DrawThreadPerContext 或者CullThreadPerCameraDrawThreadPerContext 线程模型,根据前一日中我们所知的,这两种模式中存在“上次的渲染工作与下次的更新工作交叠”这一情形
  3. 假设我们在更新工作中立即将这个节点删除,而上次渲染工作可能正要将这个节点中的数据送往OpenGL 图形渲染管线,那么灾难就发生了……

     看到这里,读者您一定已经想到了一种解决方案。对,就是在渲染后台也使用ref_ptr来引用(ref)图形节点,然后在渲染结束取消引用(unref),这样不就可以避免无谓的牺牲了吗?也省却用户的很多麻烦。说得有道理,不过这其中恐怕忽视了一个核心的问题:渲染效率。是的,假设我们要渲染成千上万个这样的几何体节点(这对您来说也许简直是家常便饭),如果每个节点的渲染都要多执行一次ref/unref 的话,效率的损失将是无法被忽略的。事实上经过测算,CPU 时间的流失大概可以达到6%,对于一个实时渲染系统来说,这的确值得斟酌。因此,OSG 的新版本中提出了DeleteHandler 的概念,也就是“垃圾收集”,把那些引用计数已经为零的对象统一收集起来,确保它们不会再被渲染线程用到之后,再在适当的地方予以释放。DeleteHandler 有一个重要的参数_numFramesToRetainObjects,它的意义是,垃圾对象被收集之后,再经过多少帧(默认设置是2),方予以释放。因此,OSG 的垃圾收集器同样需要使用DeleteHandler::setFrameNumber 来记录当前的帧数。目前,OSG 的发行版本仍然采用第一种方式,也就是渲染后台采用ref_ptr 引用计数的方式来避免删除对象造成的问题;如果您想要尝试使用和帮助调试DeleteHandler 的话,可

以在自己的程序中(main 函数之前)加入:#undef OSGUTIL_RENDERBACKEND_USE_REF_PTR以请求使用DeleteHandler。(摘自array《最长的一帧》)
 

转载地址:https://liwangjiang.blog.csdn.net/article/details/86249021 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:高通Android源码
下一篇:android广播注册不显示 BroadcastReceiver

发表评论

最新留言

很好
[***.229.124.182]2024年04月29日 11时45分18秒