请教关于C#内存泄漏的问题?
我的C#窗体去调C++的DLL用到一个Timer,在Timer中调dll处理
运行程序的时候内存每秒增长1m多,直接我机器死掉
把Timer一停就不涨了
退出程序的时候出现 “0x0d5e9578”指令引用的"0x0d613e70"内存,该内存不能为“read”。
在dll中调试,退出时出现以下
Detected memory leaks!
Dumping objects ->
{66} normal block at 0x0DD28540, 60 bytes long.
Data: < t > 10 E2 74 0D E0 01 00 00 10 01 00 00 03 00 00 00
Object dump complete.
我在Timer_Tick中把可以释放的都dispose掉了
请教各位,谢谢!什么个情况???? --------------------编程问答-------------------- 你确定C++的DLL没问题吗? --------------------编程问答-------------------- 没释放内存,查查DLL文件原编码 --------------------编程问答-------------------- 建议,在Timer中,最好是用方法变量,不要用成员变量。
在Tick 的方法中,创建对象,在完毕之后销毁对象 --------------------编程问答-------------------- 或者看看dll是否调用了一些I/O资源。
如果是这样的话,那这个dll的对象,最好是申明成 成员变量。
不要在Tick 中每次实例化出来一个新的对象。 --------------------编程问答-------------------- show your code --------------------编程问答-------------------- 你用了Timer ,它就会每隔一秒钟调用一次,你只调用不释放,当然内存都消耗没了 --------------------编程问答-------------------- .net中加载的dll一般是不能释放的。严格意义上说,,net只能变成释放某个你创建的AppDomian,而不能仅仅释放某个dll。一定要做到这一点的话,你可以创建一个AppDomain,在其中加载dll,执行完就卸载AppDomain。 --------------------编程问答-------------------- 察看msdn上的AppDomain的相关章节,有讲AppDomain的装载和卸载。 --------------------编程问答--------------------
unsafe private void videoTimer_Tick(object sender, EventArgs e)
{
image = cap.QueryFrame();
frameCount++;
int hh = image.Height;
int ww = image.Width;
int cc = image.Channels;
sbyte[] pimage = new sbyte[hh * ww * cc];
for (int i = 0; i < hh; i++)
{
for (int j = 0; j < ww; j++)
{
sbyte *value =image.GetPixelPtr(i, j);
for (int g = 0; g < cc; g++)
{
pimage[i * ww * cc + j * cc + g] = value[g];
}
}
}
bool succeeded = ObjectTracking(objs, objs.Length, pimage, ww, hh, cc);
pimage = null;
GC.Collect();
if (image == null)
{
cap.Restart();
}
Track();
image.Dispose();
}
这是C#的timer代码 image是CVImage的对象 在timer结束的时候释放! --------------------编程问答--------------------
__declspec(dllexport) bool __stdcall ObjectTracking(TxObject *object, int length,BYTE oimage[] ,int ww,int hh,int cc)
{
IplImage *pImage;
pImage = cvCreateImage(cvSize(ww,hh),8,cc);
for(int i=0;i<hh;i++)
for(int j=0;j<ww;j++)
for(int g=0;g<cc;g++)
((uchar *)(pImage->imageData+i*pImage->widthStep))[j*cc+g]=oimage[i*ww*cc+j*cc+g];
if(FlagVideoOpen)
{
//获取AVI视频帧
if(pImage == NULL)
{
return false;
}
else
{
FlagTracking = true;
}
//开始行为分析
if(FlagTracking)
{
//检测跟踪
//进行对象检测跟踪跟踪
FrameCount++;
long rate=1;//设定检测率,-1:不检测,0:只检测一次,1:逐帧检测,n:每隔n-1帧检测一次
//对象检测
TxRegion *RgnO = NULL;
long CountO=0;
//if(FrameCount%rate==0)
pDetectorObject->Detecting(pImage,false);//全局人脸检测(单独使用)
//if(FrameCount%rate==0) pDetectorObject->Detecting(pImage,false,RgnM,CountM);//运动区域人脸检测(与运动检测器(pDetectorMotion)配合使用)
CountO=pDetectorObject->GetRegion(&RgnO);
//对象跟踪,该跟踪器必须和对象检测器(pDetectorObject)配合使用
_IplImage *pImgFore=NULL;
pTrackerObject->Tracking(pImage,RgnO,CountO,object,1,pImgFore);
if(object[0].status!=0)
int i = 1;
}
else
{
//释放行为分析模块
FrameCount=0;
if(pDetectorMotion) {pDetectorMotion->Release(true); pDetectorMotion=NULL;}
if(pDetectorObject) {pDetectorObject->Release(true); pDetectorObject=NULL;}
if(pTrackerObject) {pTrackerObject->Release(true); pTrackerObject=NULL;}
if(pTrackerWhole) {pTrackerWhole->Release(true); pTrackerWhole=NULL;}
if(pTrackerUpper) {pTrackerUpper->Release(true); pTrackerUpper=NULL;}
if(pTrackerSsim) {pTrackerSsim->Release(true); pTrackerSsim=NULL;}
for(int i=0;i<N_OBJECT;i++) object[i].status=0;
}
}
else
{
if(pCapture)
{
cvReleaseCapture( &pCapture );
pCapture=NULL;
}
//释放行为分析模块
FrameCount=0;
if(pDetectorMotion) {pDetectorMotion->Release(true); pDetectorMotion=NULL;}
if(pDetectorObject) {pDetectorObject->Release(true); pDetectorObject=NULL;}
if(pTrackerObject) {pTrackerObject->Release(true); pTrackerObject=NULL;}
if(pTrackerWhole) {pTrackerWhole->Release(true); pTrackerWhole=NULL;}
if(pTrackerUpper) {pTrackerUpper->Release(true); pTrackerUpper=NULL;}
if(pTrackerSsim) {pTrackerSsim->Release(true); pTrackerSsim=NULL;}
for(int i=0;i<N_OBJECT;i++) object[i].status=0;
//结束播放
FlagVideoOpen = false; //打开标志
FlagVideoPause = false; //暂停标志
}
cvReleaseImage(&pImage);
return true;
}
C++中create一个IplImage ,然后处理!
C#的垃圾处理机制是如何的?只回收托管资源吗? --------------------编程问答-------------------- 如果是标准的dll,则可以参看
http://www.codeproject.com/csharp/dyninvok.asp
如果是.net的类库,那么内存的释放是不需要做任何事,如果想加快内存回收,可以把Assembly的加载,以及其中类型的调用封装到一个类中,然后此类型继承IDisposable接口,
参看这篇文章我提供的方法
http://community.csdn.net/Expert/TopicView1.asp?id=5023639 --------------------编程问答-------------------- 关注一下!! --------------------编程问答-------------------- 或者看看dll是否调用了一些I/O资源。
如果是这样的话,那这个dll的对象,最好是申明成 成员变量。
不要在Tick 中每次实例化出来一个新的对象。
你最好利用代理吧。开辟一个线程去执行 --------------------编程问答-------------------- 谢谢各位,在dll中定义的一个对象没有释放掉,问题解决了,呵呵!!
给分给分!!! --------------------编程问答-------------------- 对了, 有人用过OPencv吗??
在C#下如何用OpenCV得到cvCapture对象?? --------------------编程问答-------------------- c++的dll使用了指针吧
估计是内存地址错误造成 --------------------编程问答--------------------
如何释放的老兄? --------------------编程问答-------------------- --------------------编程问答-------------------- 在C#下如何用OpenCV得到cvCapture对象??
看看 这个 博客 也许对你有用
http://blog.csdn.net/converse0525/archive/2010/05/04/5556061.aspx --------------------编程问答-------------------- http://book.csdn.net/bookfiles/1173/100117335022.shtml
这个也有讲 看看吧 --------------------编程问答--------------------
.dll中内存处理问题。
楼主找到问题了吧 --------------------编程问答--------------------
正解。 --------------------编程问答-------------------- timer在dispose之前,会保持他所使用的资源。自动资源回收不会去回收。 --------------------编程问答-------------------- 快2年了还没结贴?路过 --------------------编程问答-------------------- 呵呵。路过。。
补充:.NET技术 , C#