- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我使用 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/
我是 C 新手,还没有真正掌握 C 何时决定释放对象以及何时决定保留对象。 heap_t 是指向结构堆的指针。 heap_t create_heap(){ heap_t h_t = (heap
我有一个问题,我不知道如何解决。问题是: char * ary = new Char[]; ifstream fle; fle.open(1.txt, ios_base::binary); fle.s
假设我在 C# 中有字符串:“我看不到你……” 我想删除(替换为空等)这些“’”符号。 我该怎么做? 最佳答案 那个“垃圾”看起来很像有人将 UTF-8 数据解释为 ISO 8859-1 或 Wi
我无法在解析方法中更改蜘蛛设置。但这绝对是一种方式。 例如: class SomeSpider(BaseSpider): name = 'mySpider' allowed_domains
在开始之前,我们先回顾一下堆是个什么玩意,大家可能都知道,我们每天创建的Java对象几乎都存放在堆上面,所以说堆是一个巨大的对象池一点都不过分,在这个对象池里面管理者数据巨大的对象实例。 在对
我想知道为什么 printf() 在提供数组且没有格式化选项时成功打印字符数组,但在使用整数数组时编译器会抛出警告并打印垃圾值。 这是我的代码: #include int main() { c
我正在研究 Scrapy 库并尝试制作一个小爬虫。 这是爬虫的规则: rules = ( Rule(LinkExtractor(restrict_xpaths='//div[@class="w
这个问题在这里已经有了答案: 关闭 10 年前。 Possible Duplicate: Printing a string to a temporary stream object in C++
这个问题在这里已经有了答案: Are WebGL objects garbage collected? (2 个答案) 关闭 3 年前。 在 WebGL 中,纹理的创建和销毁使用: WebGLTex
我继承了以下代码: (为保护无辜者更改了一些名称。) package foo.bar.baz; import javax.swing.JPanel; //Main panel in the GUI c
如果我没记错的话,在某些情况下,Java 中的 lambda 会生成为匿名类实例。例如,在这段代码中,lambda 需要从外部捕获一个变量: final int local = 123456; lis
我正在阅读托管代码中的内存泄漏,想知道是否可以在 C# 不安全代码中创建它? unsafe { while(true) new int; } 我不确定如果它作为不安全代码运行,是否会被 GC
假设我有以下用 HTML 编写的网页(仅正文部分): ... function fn() { // do stu
我想知道是否有简单的命令可以删除在 latex 编译过程中生成的所有不必要的文件,例如.aux、.log 等 最好将它链接到常规的 Latex 构建命令,这样在我点击“编译”后,垃圾文件就会被删除。
Java 在 Java7 中引入了带有字符串的 switch case。我想知道使用这样的开关盒是否会产生垃圾。 例如在我的程序中, String s = getString(); switch(s)
Cevelop将 char junk 作为“未初始化的变量”对象。在这种情况下,解决问题的正确方法是什么? friend std::ostream& operator>(std::istream&
关闭。这个问题需要debugging details .它目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and t
我正在编写一个发送和接收纯文本的小型 boost asio tcp 服务器和客户端。通信或多或少是请求响应。在测试期间,我想我只是向服务器发送垃圾数据,向它发送 100.000 个请求。 客户端发
我正在使用 SAX 来读取/解析 XML 文档,并且它工作正常,除了这个特定的站点,在该站点中 eclipse 告诉我“文档元素之后的垃圾”并且我没有返回任何数据 http://www.zachblu
这是我的 Scrapy 爬虫代码。我正在尝试从网站中提取元数据值。没有元数据在一个页面上出现多次。 class MySpider(BaseSpider): name = "courses"
我是一名优秀的程序员,十分优秀!