Flex VideoDisplay存在内存泄漏问题

3
实际上,我找到了解决方案,但是在之前搜索Adobe论坛和这里时,发现问题一再出现但从未得到解决,所以为了有益于未来通过谷歌搜索的人,我在这里回答自己的问题。但是无论如何,它都会泄漏,并且根据以前的评论者的判断,在各种情况下都会泄漏。在我的情况下,它在另一个SWFLoader中的SWFLoader中,在父SWFLoader消失时,视频仍然停留在内存中,而在RemovedFromStage处理程序中进行的任何removeEventListeners或gc.collect组合都无法解决问题。你可以在那里停止视频,使其不继续播放,但它仍然保留在内存中,每次运行时还会增加大约10Mb的内存。顺便说一句,我很惊讶Adobe如何让这样的事情一直没有被修复。显然,在他们自己的代码中,有一些事件侦听器被隐藏起来,但显然他们并不关心。我认为这种事情至少是Flash越来越边缘化的原因之一。对我来说,奇怪的是,许多Flash开发人员似乎也不理解这个问题,认为除非系统内存完全被消耗并且浏览器崩溃,否则这不是问题。从我自己的传统应用程序开发经验来看,看到内存每次用户按下按钮时都不断增加而从未释放,在任务管理器中看到这种情况是不可接受的。所以最初我开始寻找第三方Flex视频播放器,并立即遇到了Open Source Media Framework。在他们的软件包中,实际上有许多不同的方法和类可以调用视频。我尝试了其中的几个(MediaPlayerSprite、MediaContainer、VideoElement、LightweightVideoElement等),但所有这些都泄漏了,并且以与Flex的VideoDisplay相同的方式泄漏!显然,Flex VideoDisplay在幕后使用OSMF代码(也许)。无论如何,另一家公司不关心泄漏-令人难以置信,难以解释。
2个回答

1

只需使用原始的flash.media.Video即可。您还需要分别创建NetStream、NetConnection,并自己运行计时器,如果您想要像VideoDisplay那样自动更新播放头时间的功能。(您需要使用自己的计时器来跟踪加载进度。) 您还需要在removedFromStage处理程序中执行一些操作以避免泄漏。这实际上是至关重要的一部分,但为了初始化所有内容,可以按照以下步骤进行:

var uic:UIComponent = new UIComponent();          
var ns:NetStream;         
var v:Video = new Video();        
var nc:NetConnection = new NetConnection();      
var timer:Timer = new Timer(250);         

...

uic.addChild(v);    
this.addChild(uic);     
v.width=Number(parameters.w);   
v.height=Number(parameters.h);  

nc.connect(null);        
ns  = new NetStream(nc);        
ns.addEventListener("netStatus",play_end);  
uic.addEventListener("removedFromStage",v_remove);  

v.attachNetStream(ns);        

ns.play(session.source);        
ns.pause();         

timer.addEventListener("timer",load_handlr);        
timer.start();          

而在removedFromStage事件处理程序中:

private function v_remove(e:Event) {      

  ns.close();      
  nc.close();   

  v.attachNetStream(null);  

  timer.stop()      
}

就是这样。有趣的是,我创建的所有事件侦听器都不需要被移除,只需要停止一个计时器。还有调用nc.close等方法。(实际上不确定v.attachNetStream(null);是否严格必要)。VideoDisplay有自己的close()方法,但我已经尝试过了,对VideoDisplay中的泄漏没有影响。

所以以上操作可以停止视频并防止泄漏。在我的情况下,我希望视频一直播放到结束,因此我必须删除其他事件侦听器,以免它在循环中不断重新启动(并因此未释放内存),然后删除对ns.close的调用,以便播放到结束:

private function v_remove(e:Event) {

  nc.close();

  v.attachNetStream(null);

  timer.stop()
  timer.removeEventListener("timer",timer_handlr);
  ns.removeEventListener("netStatus",play_end);
  uic.removeEventListener("removedFromStage",v_remove);

}

所以,对于仍在进行Flash开发的人来说,这是一些有用的神秘炼金术。我想我们永远不会知道为什么Adobe不能提供一种通用方法来完全清除任意对象,自担风险。


0

不确定这是否对您有所帮助,但是在使用视频组件时(Flash而非Flex),我成功卸载了视频。除非您执行此操作(videoPlayer是我的组件实例),否则它不会清空视频(并泄漏)...

         try{

            for each(var v: VideoPlayer in videoPlayer.flvplayback_internal::videoPlayers){
                log("Cleaning up VideoPlayer:" + v);
                v.close();
                v.clear();
            }


        }catch(e:Error){
            log("EndVideo Failed: " + e);
        }

这绝对是一个Flex问题,正如我在下面指出的那样,flash.media.Video可以成功地被解除分配。实际上,在我查看的Flex/AS3层次结构中,我并没有访问名为VideoPlayer的类的权限。 - Mark

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接