QML动态创建对象出现内存泄漏

彩阳 2014-05-30 02:23:59
为了清楚地阐述我的问题,我创建了一个小小的例子程序。这个程序是基于Qt5.3构建的,是一个QtQuick工程,大家可以下载实测一下。
我使用Qt.createComponent()和Qt.createObject()来动态创建对象,在这个对象中我加入了粒子系统,可以让其运行也可以不让其运行。结果发现即使使用someObject.destory()方法也无法让系统将该对象回收,结果导致严重的内存泄漏。

// TestObject.qml
import QtQuick 2.0
import QtQuick.Particles 2.0

Rectangle
{
id: root
width: 32
height: 32
color: "#" + ( Math.floor( Math.random( ) * 0xFFFFFFFF ) ).toString( 16 )
x: Math.random( ) * parent.width
y: Math.random( ) * parent.height

NumberAnimation on x { from: parent.width / 2; to: x }
NumberAnimation on y { from: parent.height / 2; to: y }

Timer
{
id: internalTimer
interval: 2000
repeat: false
onTriggered: root.destroy( )
}

ParticleSystem
{
id: system
anchors.centerIn: parent
running: root.parent.useParticle

ImageParticle
{
source: "qrc:///particleresources/star.png"
colorVariation: 0.2
}

Emitter
{
emitRate: 100
lifeSpan: 1000
size: 40
enabled: true
velocity: AngleDirection
{
angle: 360
angleVariation: 180
magnitude: 200
magnitudeVariation: 20
}
}
}

function startTimer( ) { internalTimer.start( ) }
}


下面是主程序:

import QtQuick 2.2
import QtQuick.Controls 1.1

ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("Check memory leak")

menuBar: MenuBar {
Menu
{
title: qsTr("Option")
MenuItem
{
id: qmlTestItem
checkable: true
checked: true
text: qsTr("dynamic QML test")
}
MenuItem
{
id: useParticleItem
checkable: true
checked: false
text: qsTr( "use particle" )
}
}
}

Rectangle
{
id: qmlTestScene
anchors.fill: parent
color: "plum"
visible: qmlTestItem.checked
property bool useParticle: useParticleItem.checked

Button
{
anchors.centerIn: parent
text: qsTr( "click me to generate rectangle" )

property var testObject: Qt.createComponent( "TestObject.qml" )
onClicked:
{
var object = testObject.createObject( qmlTestScene );
object.startTimer( );
}
}
}

Text
{
anchors.right: qmlTestScene.right
anchors.bottom: qmlTestScene.bottom
text: qsTr( "made by jiangcaiyang, for test only" )
}
}

下面是程序的演示截图


←内存在点击按钮的时候一直在上升。
这里是源码,大家看看究竟有什么办法能够正确的回收对象从而避免内存泄漏。
这里
...全文
1101 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
qyvlik 2016-05-12
  • 打赏
  • 举报
回复
引用 10 楼 jiangcaiyang123 的回复:
这个问题还没有解决…………
Qt 5.5.1 暂时没有问题。
wyssailing 2015-09-08
  • 打赏
  • 举报
回复
qml性能不是很好啊,一般对于性能没有要求的加载可以在qml的部分写,对于有较高要求的都在c++测来加载qml的模块,用qquickview这个类,完成动态加载和卸载!
小小路西法 2015-04-02
  • 打赏
  • 举报
回复
楼主,我将你的代码修改为使用Loader后内存没有再一直增加 ,不过代码内去掉了button,你可以试试 // main.qml ,去掉button相关的矩形,增加Loader和定时器 Loader { id: loader onLoaded: { loader.anchors.fill=parent color: "plum" } } Timer { id: timer running: true repeat: false interval: 1000 onTriggered: { loader.source = "TestObject.qml"; loader.item.startTimer(); } }
小小路西法 2015-04-02
  • 打赏
  • 举报
回复
引用 6 楼 sdu_hanson 的回复:
[quote=引用 5 楼 jiangcaiyang123 的回复:] [quote=引用 4 楼 sdu_hanson 的回复:] [quote=引用 3 楼 jiangcaiyang123 的回复:] [quote=引用 2 楼 sdu_hanson 的回复:] [quote=引用 楼主 jiangcaiyang123 的回复:] 为了清楚地阐述我的问题,我创建了一个小小的例子程序。这个程序是基于Qt5.3构建的,是一个QtQuick工程,大家可以下载实测一下。 我使用Qt.createComponent()和Qt.createObject()来动态创建对象,在这个对象中我加入了粒子系统,可以让其运行也可以不让其运行。结果发现即使使用someObject.destory()方法也无法让系统将该对象回收,结果导致严重的内存泄漏。
创建的对象在调用destroy的时候其实已经回收了。 这么说的理由是假设把destroy去掉,占用内存增加幅度要大得多。 [/quote] 调用destory()函数(TestObject.qml的22行)并不能达到回收的效果,不管粒子系统是否存在。[/quote] 但是如果去掉这个调用的话,比加上这个调用 内存增加幅度大得多,该怎么解释呢[/quote] 那当然了,Qt文档写了,destory()是动态创建QML的对象释放的(至少是我目前看到的)唯一方法。[/quote] 所以才推断调用destroy函数已经回收了啊。。。 猜测其它方面的问题。看网上的评论,qml貌似一直有内存泄露问题。[/quote] 我在QT5.4.0是上试了你的程序,内容仍然泄露; 最近在Linux平台QT5.4.0中使用Loader控件去动态加载一个视频循环播放的qml文件,也有发现内存泄露问题;单一视频重复播放,但内存却在一点点增加;在Windows端同样程序内存虽然有增加,视频快结束时内存会释放
彩阳 2014-06-07
  • 打赏
  • 举报
回复
这个问题还没有解决…………
KeequenLiu 2014-05-31
  • 打赏
  • 举报
回复
肯定不会destory的问题了,这个不用怀疑的。 一定是你自建代码的问题,具体的只能你自己慢慢找了。给你个工具 valgrind用它来断定一下大概位置,已经集成于qtcreator 了
xianqingzh 2014-05-30
  • 打赏
  • 举报
回复
你可以去看下源码,destory做了什么东西。然后把内存前后变化都打印出来看看
sdu_hanson 2014-05-30
  • 打赏
  • 举报
回复
坐等高手来解答~~~
sdu_hanson 2014-05-30
  • 打赏
  • 举报
回复
引用 5 楼 jiangcaiyang123 的回复:
[quote=引用 4 楼 sdu_hanson 的回复:] [quote=引用 3 楼 jiangcaiyang123 的回复:] [quote=引用 2 楼 sdu_hanson 的回复:] [quote=引用 楼主 jiangcaiyang123 的回复:] 为了清楚地阐述我的问题,我创建了一个小小的例子程序。这个程序是基于Qt5.3构建的,是一个QtQuick工程,大家可以下载实测一下。 我使用Qt.createComponent()和Qt.createObject()来动态创建对象,在这个对象中我加入了粒子系统,可以让其运行也可以不让其运行。结果发现即使使用someObject.destory()方法也无法让系统将该对象回收,结果导致严重的内存泄漏。
创建的对象在调用destroy的时候其实已经回收了。 这么说的理由是假设把destroy去掉,占用内存增加幅度要大得多。 [/quote] 调用destory()函数(TestObject.qml的22行)并不能达到回收的效果,不管粒子系统是否存在。[/quote] 但是如果去掉这个调用的话,比加上这个调用 内存增加幅度大得多,该怎么解释呢[/quote] 那当然了,Qt文档写了,destory()是动态创建QML的对象释放的(至少是我目前看到的)唯一方法。[/quote] 所以才推断调用destroy函数已经回收了啊。。。 猜测其它方面的问题。看网上的评论,qml貌似一直有内存泄露问题。
彩阳 2014-05-30
  • 打赏
  • 举报
回复
引用 4 楼 sdu_hanson 的回复:
[quote=引用 3 楼 jiangcaiyang123 的回复:] [quote=引用 2 楼 sdu_hanson 的回复:] [quote=引用 楼主 jiangcaiyang123 的回复:] 为了清楚地阐述我的问题,我创建了一个小小的例子程序。这个程序是基于Qt5.3构建的,是一个QtQuick工程,大家可以下载实测一下。 我使用Qt.createComponent()和Qt.createObject()来动态创建对象,在这个对象中我加入了粒子系统,可以让其运行也可以不让其运行。结果发现即使使用someObject.destory()方法也无法让系统将该对象回收,结果导致严重的内存泄漏。
创建的对象在调用destroy的时候其实已经回收了。 这么说的理由是假设把destroy去掉,占用内存增加幅度要大得多。 [/quote] 调用destory()函数(TestObject.qml的22行)并不能达到回收的效果,不管粒子系统是否存在。[/quote] 但是如果去掉这个调用的话,比加上这个调用 内存增加幅度大得多,该怎么解释呢[/quote] 那当然了,Qt文档写了,destory()是动态创建QML的对象释放的(至少是我目前看到的)唯一方法。
sdu_hanson 2014-05-30
  • 打赏
  • 举报
回复
引用 3 楼 jiangcaiyang123 的回复:
[quote=引用 2 楼 sdu_hanson 的回复:] [quote=引用 楼主 jiangcaiyang123 的回复:] 为了清楚地阐述我的问题,我创建了一个小小的例子程序。这个程序是基于Qt5.3构建的,是一个QtQuick工程,大家可以下载实测一下。 我使用Qt.createComponent()和Qt.createObject()来动态创建对象,在这个对象中我加入了粒子系统,可以让其运行也可以不让其运行。结果发现即使使用someObject.destory()方法也无法让系统将该对象回收,结果导致严重的内存泄漏。
创建的对象在调用destroy的时候其实已经回收了。 这么说的理由是假设把destroy去掉,占用内存增加幅度要大得多。 [/quote] 调用destory()函数(TestObject.qml的22行)并不能达到回收的效果,不管粒子系统是否存在。[/quote] 但是如果去掉这个调用的话,比加上这个调用 内存增加幅度大得多,该怎么解释呢
彩阳 2014-05-30
  • 打赏
  • 举报
回复
引用 2 楼 sdu_hanson 的回复:
[quote=引用 楼主 jiangcaiyang123 的回复:] 为了清楚地阐述我的问题,我创建了一个小小的例子程序。这个程序是基于Qt5.3构建的,是一个QtQuick工程,大家可以下载实测一下。 我使用Qt.createComponent()和Qt.createObject()来动态创建对象,在这个对象中我加入了粒子系统,可以让其运行也可以不让其运行。结果发现即使使用someObject.destory()方法也无法让系统将该对象回收,结果导致严重的内存泄漏。
创建的对象在调用destroy的时候其实已经回收了。 这么说的理由是假设把destroy去掉,占用内存增加幅度要大得多。 [/quote] 调用destory()函数(TestObject.qml的22行)并不能达到回收的效果,不管粒子系统是否存在。
sdu_hanson 2014-05-30
  • 打赏
  • 举报
回复
引用 楼主 jiangcaiyang123 的回复:
为了清楚地阐述我的问题,我创建了一个小小的例子程序。这个程序是基于Qt5.3构建的,是一个QtQuick工程,大家可以下载实测一下。 我使用Qt.createComponent()和Qt.createObject()来动态创建对象,在这个对象中我加入了粒子系统,可以让其运行也可以不让其运行。结果发现即使使用someObject.destory()方法也无法让系统将该对象回收,结果导致严重的内存泄漏。
创建的对象在调用destroy的时候其实已经回收了。 这么说的理由是假设把destroy去掉,占用内存增加幅度要大得多。
sdu_hanson 2014-05-30
  • 打赏
  • 举报
回复
这东西真恐怖,本来觉得增加到一定程度内存不会再增加了。 改了改代码每点击一次代码循环1000次,点个三四十下就内存不足了。

16,229

社区成员

发帖
与我相关
我的任务
社区描述
Qt 是一个跨平台应用程序框架。通过使用 Qt,您可以一次性开发应用程序和用户界面,然后将其部署到多个桌面和嵌入式操作系统,而无需重复编写源代码。
社区管理员
  • Qt
  • 亭台六七座
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧