GC 使 QML 应用程序崩溃
GC crashes QML-Application
不要害怕!这不是生产代码。这只是为了学习有关QML的新知识! 我不寻求'你不要做这样的事情——那样做'。 我对QML的内部更感兴趣
考虑以下 QML 代码
import QtQuick 2.4
import QtQuick.Window 2.0
Window {
id: root
width: 800
height: 600
visible: true
GridView {
width: 800
height: 200
model: 4000
flow: GridView.FlowTopToBottom
delegate: Rectangle {
id: myDelegate
width: 100
height: 100
border.width: 1
Column {
anchors.fill: parent
Text {
text: index
height: 20
width: parent.width
}
Item {
id: frame0
height: 20
width: parent.width
}
Item {
id: frame1
height: 20
width: parent.width
}
}
Component.onCompleted: {
// if (index % 100 === 0) gc()
frame0.children = [myComp.createObject(myDelegate)]
frame1.children = [myComp.createObject(null)]
frame0.children[0].text = 'QML ' + index
frame1.children[0].text = 'JS ' + index
}
}
Component {
id: myComp
Text {
anchors.centerIn: parent
Component.onDestruction: console.log('Destroy ' + text)
}
}
}
}
它在一定程度上说明了使用动态对象创建(JS(时QML的内存管理。我有一个ListView
,它创建了一些委托,并让我浏览它们,按需创建新的代表。
诀窍是:创建新委托时,它使用JavaScript
动态对象创建来创建文本对象的两个实例。
其中一个是委托的父级,另一个是null
的父级,因此它的生命周期由 JS-Engine 决定。一旦没有指针,它应该被垃圾回收,指向它。
首先,我将将它们都放在一个frame
(Item
(中以显示(设置视觉父级(。作为委托,这些帧将被销毁。正如预期的那样,这将销毁将委托作为父级的动态创建的对象。另一个(应该(留给垃圾收集器来完成他的工作。
这就是它失败的地方 - 有时应用程序在 GC 启动之前崩溃,有时它会崩溃,而 GC 正在尝试完成其工作。
尽管文档不推荐它,但它确实有帮助,手动调用 GC(激活 Component.onCompleted
中注释掉的行(。
所以在我看来,GC 高估了它的能力,并决定在已经很晚的时候开始行动。
这可能是什么原因?有没有办法告诉总理事会积极主动?
再次:我不打算在我的代码中使用带有
.createObject(null)
的动态对象创建。这是纯粹的好奇心。
这可能是什么原因?有没有办法告诉GC 主动?
其原因是有缺陷的qtquick对象生命周期实现。在这一点上,它看起来不是JS的东西,而是一个qtquick的东西。它显然不遵守自己所谓的规则 - 例如,它会删除仍在使用中的父对象,从而导致硬崩溃。您不能指望引用计数也能正常工作。此行为可能发生在许多采用动态的方案中,它通常不会在琐碎和静态方案中表现出来。
如链接问题中所述,解决方案是使用手动对象生存期管理。使用一组新功能来创建和删除对象。
- 对于创建,您必须将对象传递给C++端才能在其上调用
QQmlEngine::setObjectOwnership(ojb, QQmlEngine::CppOwnership);
,这基本上告诉 qtQuick"甚至不要费心尝试",幸运的是,至少这应该像它应该的那样工作 - 对于销毁,您必须将对象传递给C++端才能调用
obj->deleteLater();
对我来说,这确实可以解决问题,我不再无缘无故地崩溃。使用自定义生命周期管理并远离库存功能。它为您提供了保证,只要您需要它,该对象就会保持活动状态,但它也不会停留在您希望它消失的点之后,这是另一个问题,尽管不是那么严重。当然,这消除了使用 JS 的便利因素,因为您必须放弃自动生命周期管理,并对自己的代码更加勤奋和明确,但对此您无能为力。尽管该错误在大约一年前被报告并被认为是关键的,但尚未对此进行任何工作。因此,我认为,尽管它的严重性可能很关键,但在找到原因和修复它时,它更像是最低优先级。
- Grunt构建导致Angular应用程序在dist上崩溃
- Cordova/PhoneGap:使用谷歌地图API的应用程序崩溃
- Phonegap摄像头应用程序崩溃
- IE 10在web应用程序中崩溃
- Android应用程序在接收intent捆绑包时崩溃
- PhoneGap(Cordova)应用程序加载谷歌图表API时崩溃
- IE11在基于Kendo/JavaScript的web应用程序中崩溃
- 如果我刷新几次,为什么我的应用程序会在Chrome中崩溃
- 如何使我的phonegap android应用程序崩溃
- Node webkit 应用程序在加载 Vimeo 视频时崩溃
- 通过App Store更新基于Cordova/Phonegap的应用程序“崩溃”
- AngularJS应用程序使IE开发工具崩溃
- 我的安卓应用程序崩溃了,但我看不出出了什么问题
- Iron Router,Meteor 应用程序崩溃时 router.js 被放置在 /lib 中
- 在流星中使用会话时应用程序崩溃
- React Native - Android应用程序在调试上工作,在发布时崩溃
- window.open() 使我的应用程序在 Blackberry10 上崩溃
- 你好世界电话差距应用程序崩溃
- 由点击查看导致的应用程序崩溃
- IOS Cordova Push插件- Coldstart崩溃应用程序