gpt4 book ai didi

javascript - console.log() 会触发垃圾回收吗?

转载 作者:行者123 更新时间:2023-11-29 02:26:10 26 4
gpt4 key购买 nike

我使用 Cordova 为 iOS 和 Android 编写了一个混合游戏。在某些 Android 设备上,游戏会在几分钟后崩溃,屏幕上会显示一条消息“(应用程序名称)已停止”。在过去的一周里,我一直在努力寻找导致它崩溃的原因,但一直找不到。我已经开始讨论这个话题,但今天我观察到一些值得单独讨论的话题。请允许我先告诉您有关崩溃的一些信息,以及我为解决该崩溃所做的工作。

游戏使用两个 Canvas 。一个是不可见的,不是 DOM (MAINCanvas) 的一部分,并且无论实际屏幕尺寸如何,它始终具有固定大小。所有绘图都在该 Canvas 上完成。另一个与屏幕大小相同且可见的 Canvas (DISPLAYCanvas)。我在游戏开始时存储这些 Canvas 的上下文:

var MAINCanvas = document.createElement( "canvas" );
var DISPLAYCanvas = document.createElement( "canvas" );

document.body.appendChild(DISPLAYCanvas);

MAINCanvas.context = MAINCanvas.getContext("2d", { alpha: false } );
DISPLAYCanvas.context = DISPLAYCanvas.getContext("2d", { alpha: false } );

我的游戏的主循环是这样的:

function MainLoop() {
doStuff();
doSomeMoreStuff();
Render(); // This renders all game elements on the invisible MAINCanvas

DISPLAYCanvas.context.drawImage( MAINCanvas, 0, 0 );

window.requestAnimationFrame( MainLoop );
}

玩了几分钟后,游戏每次都崩溃。为了找出它崩溃的地方,我添加了一些 console.logs:

function MainLoop() {
console.log( "Stuff" );
doStuff();
console.log( "SomeMoreStuff" );
doSomeMoreStuff();
console.log( "Render" );
Render(); // This renders all game elements on the invisible MAINCanvas

console.log( "Draw" );
DISPLAYCanvas.context.drawImage( MAINCanvas, 0, 0 );

window.requestAnimationFrame( MainLoop );
}

事实证明,它在不同的地方崩溃了。

然后我怀疑这可能是罪魁祸首:

MAINCanvas.context = MAINCanvas.getContext("2d", { alpha: false } );
DISPLAYCanvas.context = DISPLAYCanvas.getContext("2d", { alpha: false } );

我正在向一个 DOM 对象添加属性,我记得在某处读到过一个禁忌,它可以防止对象(的副本)被垃圾回收。所以我改变了它:

var MAINContext = MAINCanvas.getContext("2d", { alpha: false } );
var DISPLAYContext = DISPLAYCanvas.getContext("2d", { alpha: false };

我的主循环到:

function MainLoop() {
console.log( "Stuff" );
doStuff();
console.log( "SomeMoreStuff" );
doSomeMoreStuff();
console.log( "Render" );
Render(); // This renders all game elements on the invisible MAINCanvas

console.log( "Draw" );
DISPLAYContext.drawImage( MAINCanvas, 0, 0 );

window.requestAnimationFrame( MainLoop );
}

而且它不再崩溃了!经过 7 天纯粹令人沮丧的调试后,我终于找到了导致它崩溃的原因,我感到非常高兴。我现在可以毫无问题地玩游戏了。

因此,为了准备发布游戏,我删除了 console.log() 行。可以肯定的是,我再次测试了游戏,然后……几分钟后它崩溃了。所以我在主循环中添加了一个 console.log:

function MainLoop() {
console.log( "Stuff" );
doStuff();
doSomeMoreStuff();
Render(); // This renders all game elements on the invisible MAINCanvas

DISPLAYContext.drawImage( MAINCanvas, 0, 0 );

window.requestAnimationFrame( MainLoop );
}

再次测试,没有崩溃。删除了 console.log() 并崩溃了。我已经尝试了几次,每次删除 console.log() 时,游戏都会崩溃。如果我添加它,它不会。始终如一。

我现在唯一能想到的是 console.log 以某种方式触发垃圾收集?

最佳答案

在我看来,这是 console.log() 在生命周期中造成的延迟。

过去有过类似的问题。

尝试将代码包装在延迟为 0 秒的超时中,以便线程运行该循环。

示例

function MainLoop() {
//console.log("MainLoop start");
doStuff();
doSomeMoreStuff();
Render(); // This renders all game elements on the invisible MAINCanvas

DISPLAYContext.drawImage( MAINCanvas, 0, 0 );

window.setTimeout(function(){
window.requestAnimationFrame( MainLoop );
},0);
}

也许可以使用它并以相同的方式添加其他密集操作。

编辑:您也可以尝试降低帧率 - 也许这些特殊的 Android 设备没有足够的能力来处理帧率......

示例

var framesPerSecond = 10;

function MainLoop() {
//console.log("MainLoop start");
doStuff();
doSomeMoreStuff();
Render(); // This renders all game elements on the invisible MAINCanvas

DISPLAYContext.drawImage( MAINCanvas, 0, 0 );

window.setTimeout(function(){
window.requestAnimationFrame( MainLoop );
}, (1000 / framesPerSecond));
}

希望这能有所帮助。

尽情享受吧!

关于javascript - console.log() 会触发垃圾回收吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52097191/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com