S
Sachow
Unregistered / Unconfirmed
GUEST, unregistred user!
最近小弟受上司之命,要做一个屏幕保护程序,以作为公司的形象宣传手段之一,现在程序最近小弟受上司之命,要做一个屏幕保护程序,以作为公司的形象宣传手段之一,现在程序
已经完成,但发现一个致命问题:内存泄漏!每当程序运行到超过30分钟以上(按每3秒切
换一次图片来计)时就会耗尽内存而死机。
由于代码很长,不能全部贴出来,我就简单地描述一下程序结构:程序主要有两个部分,
一是主窗体,用来接受用户的输入及画图,二是一个线程对象,用来不停地执行画图函数。
这个线程很简单,只有下列语句:(请别见怪,这是C++ Builder做的,我认为可以与Delphi
代码一视同仁)
void __fastcall SvrThrd::Execute(void)
{
while(!Terminated){
Sleep(SvrForm->IntervalTime); //切换图片的间隔
SvrForm->PlayPic(); //执行主窗体的切换图片函数
}
}
而所有的变量及功能函数都是定义在主窗体SvrForm中的,属于窗体类的成员方法,它们
包括读取文件头的函数,读取文件信息表的函数,读取图片的函数,画图函数及调用画图
函数的辅助函数等,补充一下,我的屏保数据文件是用TFileStream写入的文件,它包括了
一个文件头,三个文件信息表和数据段,读取的时候也是用TFileStream来读出的,由于数
据文件中的图片都是Jpeg图片,因此我的读取图片方式是用是TJPEGImage::LoadFromStream()。
下面的读取图片函数:
//---------------------------------------------------------------------------
bool __fastcall TSvrForm::LoadPic(Graphics::TBitmap *Dest)
{
/* 为了考虑性能,我把下面的变量都设成了公有或私有变量,而不是局部变量 */
try{
MM->Seek(PicInfo[PicIndex].FileBegin, soFromBeginning);
//MM是一个TfileStream*,由FormCreate时初始化
//PicInfo是图片信息表结构指针数组,由读取文件信息表函数读得其值
//PicIndex是一个全局整型变量,用来标识当前读取的图片序号
if (PicInfo[PicIndex].FileType == 1){ //资源为Bmp图片
Dest->LoadFromStream(MM);
}
else if (PicInfo[PicIndex].FileType == 2){ //资源为Jpeg图片
//tmpjpg是一个TJPEGImage*,由FormCreate时初始化
//怀疑以下两句可能有导致内存泄漏的因素
tmpjpg->LoadFromStream(MM);
Dest->Assign(tmpjpg);
}
if (PicIndex<PFH.PictureCount-1)
//PFH是文件头结构,其PictureCount成员标识了数据文件中的图片数量
//PFH结构由读取文件头函数读得其值
PicIndex++;
else
PicIndex = 0;
return true;
}
catch(...){
return false;
}
}
//---------------------------------------------------------------------------
列出此函数是因为该函数是程序中仅有的两个反复地被线程执行的函数之一,另一个是
画图函数,它只是简单地执行画布的矩形拷贝(Canvas->CopyRect()),因些不被考
虑为导致内存泄漏的原因之一,在每次画完图(即完成图片切换效果的绘制)后才执行
读入图片LoadPic函数。
我认为可能导致内存泄漏的地方有以下方面:
1、TJPEGImage::LoadFromStream()有问题;
2、位图的Assign(tmpjpg)有问题;
3、通过一个线程对象去执行另一个类的方法会出问题;
在先前我的LoadPic函数中用的tmpjpg和MM都还是局部变量,因此每次都要用new
来分配内存,用delete来释放内存,这样执行次数多了以后,更增加了内存碎片的产
生,故才改为SvrForm窗体类的私有变量。
望各位大侠帮忙分析一下问题是出在哪里的,另外如果谁能给我一份Bounds Checker
for C++ Builder就更好了,万分感激!此题目(200+)的意思是不够再加!
已经完成,但发现一个致命问题:内存泄漏!每当程序运行到超过30分钟以上(按每3秒切
换一次图片来计)时就会耗尽内存而死机。
由于代码很长,不能全部贴出来,我就简单地描述一下程序结构:程序主要有两个部分,
一是主窗体,用来接受用户的输入及画图,二是一个线程对象,用来不停地执行画图函数。
这个线程很简单,只有下列语句:(请别见怪,这是C++ Builder做的,我认为可以与Delphi
代码一视同仁)
void __fastcall SvrThrd::Execute(void)
{
while(!Terminated){
Sleep(SvrForm->IntervalTime); //切换图片的间隔
SvrForm->PlayPic(); //执行主窗体的切换图片函数
}
}
而所有的变量及功能函数都是定义在主窗体SvrForm中的,属于窗体类的成员方法,它们
包括读取文件头的函数,读取文件信息表的函数,读取图片的函数,画图函数及调用画图
函数的辅助函数等,补充一下,我的屏保数据文件是用TFileStream写入的文件,它包括了
一个文件头,三个文件信息表和数据段,读取的时候也是用TFileStream来读出的,由于数
据文件中的图片都是Jpeg图片,因此我的读取图片方式是用是TJPEGImage::LoadFromStream()。
下面的读取图片函数:
//---------------------------------------------------------------------------
bool __fastcall TSvrForm::LoadPic(Graphics::TBitmap *Dest)
{
/* 为了考虑性能,我把下面的变量都设成了公有或私有变量,而不是局部变量 */
try{
MM->Seek(PicInfo[PicIndex].FileBegin, soFromBeginning);
//MM是一个TfileStream*,由FormCreate时初始化
//PicInfo是图片信息表结构指针数组,由读取文件信息表函数读得其值
//PicIndex是一个全局整型变量,用来标识当前读取的图片序号
if (PicInfo[PicIndex].FileType == 1){ //资源为Bmp图片
Dest->LoadFromStream(MM);
}
else if (PicInfo[PicIndex].FileType == 2){ //资源为Jpeg图片
//tmpjpg是一个TJPEGImage*,由FormCreate时初始化
//怀疑以下两句可能有导致内存泄漏的因素
tmpjpg->LoadFromStream(MM);
Dest->Assign(tmpjpg);
}
if (PicIndex<PFH.PictureCount-1)
//PFH是文件头结构,其PictureCount成员标识了数据文件中的图片数量
//PFH结构由读取文件头函数读得其值
PicIndex++;
else
PicIndex = 0;
return true;
}
catch(...){
return false;
}
}
//---------------------------------------------------------------------------
列出此函数是因为该函数是程序中仅有的两个反复地被线程执行的函数之一,另一个是
画图函数,它只是简单地执行画布的矩形拷贝(Canvas->CopyRect()),因些不被考
虑为导致内存泄漏的原因之一,在每次画完图(即完成图片切换效果的绘制)后才执行
读入图片LoadPic函数。
我认为可能导致内存泄漏的地方有以下方面:
1、TJPEGImage::LoadFromStream()有问题;
2、位图的Assign(tmpjpg)有问题;
3、通过一个线程对象去执行另一个类的方法会出问题;
在先前我的LoadPic函数中用的tmpjpg和MM都还是局部变量,因此每次都要用new
来分配内存,用delete来释放内存,这样执行次数多了以后,更增加了内存碎片的产
生,故才改为SvrForm窗体类的私有变量。
望各位大侠帮忙分析一下问题是出在哪里的,另外如果谁能给我一份Bounds Checker
for C++ Builder就更好了,万分感激!此题目(200+)的意思是不够再加!