刚写了一个软件,用在工业现场,软件要长期不间断的运行
完成后,发现可用内存不断减少(用一个名叫Ram Idle的软件监视的内存)。
软件运行在98平台。
做了很长时间的努力好像效果不大,现求助各位高手了。由于内容有点长,不让我发出去,所以分成四个部分了,各位高手们如果有兴趣帮忙可以给我E_MIAL地址,我发给你们。
软件可能出问题的地方在如下几个方面。
1。有一个结构数组
   struct m_structData
{
int m_guan;
float m_yewei;
float m_qiwen;
float m_youwen;
int m_TQ;
int m_BTQ;
int m_PW;
int m_BPW;
int m_DT;
int m_BDT;
int m_window;
float m_T[15];
//
float m_midu;
float m_rongji;
float m_zhongliang;
CString m_guanhao;
bool m_baojin;
float m_lastyewei;
bool  m_boolBaojin;//定义是否有过报警了

}
m_important[4][4];
  这个结构数组是全局变量,通讯时要不断改变这个结构中的值。
2。开了三个线程
   程序启动时,开启2个线程。函数如下:
      CWinThread *pThread1=AfxBeginThread(ThreadFunc1,this);
CWinThread *pThread2=AfxBeginThread(ThreadFunc2,this);
         thread1=pThread1->m_hThread;
thread2=pThread2->m_hThread;
   这两个线程都用来做通信。线程函数中都用的是while()死循环。里面的操作就是
   和下位机进行通信,通信成功后,修改上面结构数组中的数据。并进行一些数  据   处  理

  第三个线程主要用来做局域网通信。也有一个全局句柄HANDLE thread3;每隔3秒就进行如下调用
    CWinThread *pThread=AfxBeginThread(ThreadFunc3,this);
    thread3=pThread->m_hThread;
不过这个线程不是while循环了。
4。数据处理部分
   我从CDaoRecordset 派生了几个类m_rongji_recordret。干脆给出原代码
    WIN32_FIND_DATA fd1;
CString sss;
         sss.Format("容积表\\%s.mdb",m_setupData[m_i][m_j].m_guanname);
HANDLE hFind=::FindFirstFile(sss,&fd1);
if(hFind!=INVALID_HANDLE_VALUE)
{
    m_rongji_database.Open(sss);     m_rongji_recordret.m_pDatabase=&m_rongji_database;
    m_rongji_recordret.Open();
   m_rongji_recordret.MoveFirst(); 
   m_rongji_recordret.Move(m_movek+1);
m_important[m_i][m_j].m_rongji=m_rongji_recordret.m_column3;
m_rongji_recordret.Close();
m_rongji_database.Close();

}
else 

  m_important[m_i][m_j].m_rongji=0.f;

::FindClose(hFind);
5.绘图
  绘图的源代码如下:(说明,每当通信完成就要调用这一段代码)
    CWnd *pWnd=GetDlgItem(IDC_STATIC_PICTURE);
CDC *dc=pWnd->GetDC();
CDC memDC;memDC.CreateCompatibleDC(dc); if(paint)
{
pWnd->Invalidate();
pWnd->UpdateWindow();
}
CBitmap bitmap;
CRect clientRect;
pWnd->GetClientRect(clientRect);
bitmap.LoadBitmap(IDB_BITMAP1);
CBitmap *oldbitmap=memDC.SelectObject(&bitmap);
CBrush brush;
brush.CreateSolidBrush(RGB(0,0,180));
memDC.FillRect(clientRect,&brush);
INT width=clientRect.Width()/4;
INT height=clientRect.Height()/4;
CPen pen;CPen *oldPen;
         pen.CreatePen(PS_SOLID,2,RGB(255,255,255));
oldPen=(CPen*)memDC.SelectObject(&pen);
int i;
for(i=0;i<5;i++)
{
memDC.MoveTo(0,i*height);
memDC.LineTo(clientRect.right,i*height);
}
for(i=0;i<5;i++)
{
memDC.MoveTo(i*width,0);
memDC.LineTo(i*width,clientRect.bottom );
}
CRect rect[4][4];
int j;
for(i=0;i<4;i++)
for(j=0;j<4;j++)
{
rect[i][j].left =j*width;
rect[i][j].top=i*height;
rect[i][j].right=(j+1)*width;
rect[i][j].bottom=(i+1)*height;
}
CRect smallrect[4][4];
CRect m_rect1[4][4];
for(i=0;i<4;i++)
         for(j=0;j<4;j++)
         {
  smallrect[i][j].left=rect[i][j].left+10;
  smallrect[i][j].right=(long)(smallrect[i][J].left+1/5.0*rect[i][j].Width());
  smallrect[i][j].top=rect[i][j].top +30;
  smallrect[i][j].bottom=rect[i][j].bottom-20;
           m_rect1[i][j].left=smallrect[i][j].left;
 m_rect1[i][j].right =smallrect[i][j].right;
m_rect1[i][j].bottom =smallrect[i][j].bottom;
m_rect1[i][j].top=(int)(smallrect[i][j].bottom-(m_important[i][j].m_yewei/15.0)*smallrect[i][j].Height());
} CBrush brush1;brush1.CreateSolidBrush(RGB(255,255,255));
CBrush brushnew;brushnew.CreateSolidBrush(RGB(0,255,0));
CBrush baojinbrush(RGB(255,128,64));
for(i=0;i<4;i++)
for(j=0;j<4;j++)
{
  memDC.FillRect(smallrect[i][j],&brush1);
  if(m_important[i][j].m_baojin)
  {
    memDC.FillRect(m_rect1[i][j],&baojinbrush);   }
 else 
memDC.FillRect(m_rect1[i][j],&brushnew);  }
TEXTMETRIC tm;
memDC.GetTextMetrics(&tm);
int h=tm.tmHeight+tm.tmExternalLeading;
int w=tm.tmAveCharWidth;
memDC.SetBkMode(TRANSPARENT);
           for(i=0;i<4;i++)
  for(j=0;j<4;j++)
  {
    memDC.SetTextColor(RGB(0,255,0));
   CString st;
   st.Format("罐号:%s",m_setupData[i][j].m_guanname);
   memDC.TextOut(smallrect[i][j].left,smallrect[i][j].top-20,st);
   memDC.SetTextColor(RGB(215,215,215));
  st.Format("液位:%.3f米",m_important[i][j].m_yewei);
  memDC.TextOut(smallrect[i][j].right+35,smallrect[i][j].top-h,st);
           st.Format("气温:%.3f℃",m_important[i][j].m_qiwen);
  memDC.TextOut(smallrect[i][j].right+35,smallrect[i][j].top,st);
st.Format("油温:%.3f℃",m_important[i][j].m_youwen);
memDC.TextOut(smallrect[i][j].right+35,smallrect[i][j].top+1*h,st);
         st.Format("容积:%.3f方",m_important[i][j].m_rongji);
memDC.TextOut(smallrect[i][j].right+35,smallrect[i][j].top+2*h,st);
        st.Format("重量:%.3f吨",m_important[i][j].m_zhongliang);
        memDC.TextOut(smallrect[i][j].right+35,smallrect[i][j].top+3*h,st);
       st.Format("密度:%.3f",m_important[i][j].m_midu);
       memDC.TextOut(smallrect[i][j].right+35,smallrect[i][j].top+4*h,st);
   
     }


dc->BitBlt(0,0,clientRect.Width(),clientRect.Height(),&memDC,0,0,SRCCOPY);
    memDC.SelectObject(oldPen);
memDC.SelectObject(oldbitmap);
pen.DeleteObject();
bitmap.DeleteObject();
//brush.DeleteObject();
//brush1.DeleteObject();brushnew.DeleteObject();
memDC.DeleteDC();
pWnd->ReleaseDC(dc);大概就是这样了,应用时,发现内存耗的很厉害,运行了一段时间后,居然会死机。
不过98系统报的不是内存不足,就说是程序内部错误。但用内存监视时发现可用内存在不断减少。
我做通信用的是WIN32API。由于要用到两个串口,所以程序启动时,有如下两个操作。 CString str_comm;
str_comm.Format("COM%d",m_com1);
   commDev1 = CreateFile(str_comm,  GENERIC_READ | GENERIC_WRITE, 
0, NULL,  OPEN_EXISTING,  0,NULL);
if(commDev1 == INVALID_HANDLE_VALUE) 
{
SetWindowText("该端口已经被使用,或者该端口无效");
        CloseHandle(commDev1);
}
     str_comm.Format("COM%d",m_com2);
 commDev2 = CreateFile(str_comm,GENERIC_READ | GENERIC_WRITE, 
0, 
NULL, 
OPEN_EXISTING, 
0, 
NULL);
if(commDev2 == INVALID_HANDLE_VALUE) 
{
   SetWindowText("该端口已经被使用,或者该端口无效");
    CloseHandle(commDev1);

}    
就是这样,感谢你们的帮忙
我的QQ是:35945968
   E_MAIL:[email protected]

解决方案 »

  1.   

    前面放不下,所以后一段写在这里了
    //注。commDev1,和commDev2都是全局变量。HANDLE commDev1,commDev2;
    线程1,和线程2的函数类似,如下:
    UINT ThreadFunc1(LPVOID pParam)
    {
    CMyDlg*pWnd=(CMyDlg*)pParam;
    DCB dcb;  
    GetCommState(pWnd->commDev1, &dcb);
    dcb.BaudRate =9600;
    dcb.Parity = NOPARITY;
    dcb.ByteSize = 8;
    dcb.StopBits = ONESTOPBIT;
    SetCommState(pWnd->commDev1, &dcb);
    COMMTIMEOUTS tout;
    GetCommTimeouts(pWnd->commDev1, &tout);
    tout.ReadIntervalTimeout = 5000; //1000
    tout.ReadTotalTimeoutMultiplier = 5; //3
             tout.ReadTotalTimeoutConstant = 5000; //1000
    SetCommTimeouts(pWnd->commDev1, &tout);
    int kk=0;
    while(pWnd->open)
    {
     // pWnd->GetDlgItem(IDC_EDIT1)->SetWindowText("");
    unsigned char  ReceiveCommand[390]; //接收指令
    DWORD inNumber;
    DWORD Number = 1;      
    ReadFile(pWnd->commDev1, ReceiveCommand, 1, &inNumber, NULL); if(inNumber < 1 || ReceiveCommand[0]!= 0x53)
    {

     continue;
    }
    ReadFile(pWnd->commDev1, ReceiveCommand, 1, &inNumber, NULL);

    if(inNumber < 1 || ReceiveCommand[0]!= 0xb3)
    {

    continue;
    }
    ReadFile(pWnd->commDev1, ReceiveCommand, 1, &inNumber, NULL);

    if(inNumber < 1 || ReceiveCommand[0]!= 0xd8)
    {

    continue;
    }

          ReadFile(pWnd->commDev1, ReceiveCommand, 387, &inNumber, NULL);
    int i;

    BYTE Rec[390];
    Rec[0]=0x53;Rec[1]=0xb3;Rec[2]=0xd8;
    for(i=0;i<387;i++)
    {
    Rec[i+3]=ReceiveCommand[i];
    }
      
    BYTE CRC=pWnd->Crc(Rec,389);


       if(CRC==Rec[389])
       {
       INT m_datacount=ReceiveCommand[0]*256+ReceiveCommand[1];//数据个数
       int i;int j;
       for(i=0;i<2;i++)
       for(j=0;j<4;j++)
       {
        pWnd->m_important[i][j].m_guan=ReceiveCommand[2+j*48+i*192]*256+ReceiveCommand[3+j*48+i*192];
       pWnd->m_important[i][j].m_yewei=float((ReceiveCommand[4+j*48+i*192]*256+ReceiveCommand[5+j*48+i*192])/1000.0);
                if((pWnd->m_important[i][j].m_yewei>=pWnd->m_setupData[i][j].m_gaowei)||(pWnd->m_important[i][j].m_yewei<=pWnd->m_setupData[i][j].m_diwei)&&pWnd->m_important[i][j].m_yewei>0.f)
    pWnd->m_important[i][j].m_baojin=true;
    else 
     pWnd->m_important[i][j].m_baojin=false;
    pWnd->m_important[i][j].m_midu=pWnd->m_setupData[i][j].m_midu;
             bool have=false;
    if(ReceiveCommand[6+j*48+i*192]&0x80)
    {
       ReceiveCommand[6+j*48+i*192]-=0x80;
       pWnd->m_important[i][j].m_qiwen=(float)(-1.0*float((ReceiveCommand[6+j*48+i*192]*256+ReceiveCommand[7+j*48+i*192])/100.0));
    }
    else 
    pWnd->m_important[i][j].m_qiwen=float((ReceiveCommand[6+j*48+i*192]*256+ReceiveCommand[7+j*48+i*192])/100.0);
             if(ReceiveCommand[8+j*48+i*192]&0x80)
    {
      ReceiveCommand[8+j*48+i*192]-=0x80;
    pWnd->m_important[i][j].m_youwen=float(-1.0*float((ReceiveCommand[8+j*48+i*192]*256+ReceiveCommand[9+j*48+i*192])/100.0));
    }
    else 
    pWnd->m_important[i][j].m_youwen=float((ReceiveCommand[8+j*48+i*192]*256+ReceiveCommand[9+j*48+i*192])/100.0);
    pWnd->m_important[i][j].m_TQ=ReceiveCommand[10+j*48+i*192]*256+ReceiveCommand[11+j*48+i*192];
    pWnd->m_important[i][j].m_BTQ=ReceiveCommand[12+j*48+i*192]*256+ReceiveCommand[13+j*48+i*192];
    pWnd->m_important[i][j].m_PW=ReceiveCommand[14+j*48+i*192];
    pWnd->m_important[i][j].m_BPW=ReceiveCommand[15+j*48+i*192];
    pWnd->m_important[i][j].m_DT=ReceiveCommand[16+j*48+i*192];
    pWnd->m_important[i][j].m_BDT=ReceiveCommand[17+j*48+i*192];
    pWnd->m_important[i][j].m_window=ReceiveCommand[18+j*48+i*192]*256+ReceiveCommand[19+j*48+i*192];
            if(ReceiveCommand[20+j*48+i*192]&0x80)
    {
    ReceiveCommand[20+j*48+i*192]-=0x80;
    pWnd->m_important[i][j].m_T[0]=(float)(-1.0*float((ReceiveCommand[20+j*48+i*192]*256+ReceiveCommand[21+j*48+i*192])/100.0));
    }
    else
    pWnd->m_important[i][j].m_T[0]=float((ReceiveCommand[20+j*48+i*192]*256+ReceiveCommand[21+j*48+i*192])/100.0);
    if(ReceiveCommand[22+j*48+i*192]&0x80)
    {
    ReceiveCommand[22+j*48+i*192]-=0x80;
    pWnd->m_important[i][j].m_T[1]=float(-1.0*float((ReceiveCommand[22+j*48+i*192]*256+ReceiveCommand[23+j*48+i*192])/100.0));
    }
    else
    pWnd->m_important[i][j].m_T[1]=float((ReceiveCommand[22+j*48+i*192]*256+ReceiveCommand[23+j*48+i*192])/100.0);

    if(ReceiveCommand[24+j*48+i*192]&0x80)
    {
    ReceiveCommand[24+j*48+i*192]-=0x80;
    pWnd->m_important[i][j].m_T[2]=float(-1.0*float((ReceiveCommand[24+j*48+i*192]*256+ReceiveCommand[25+j*48+i*192])/100.0));
    }
    else
             pWnd->m_important[i][j].m_T[2]=float((ReceiveCommand[24+j*48+i*192]*256+ReceiveCommand[25+j*48+i*192])/100.0);         if(ReceiveCommand[26+j*48+i*192]&0x80)
    {
    ReceiveCommand[26+j*48+i*192]-=0x80;
    pWnd->m_important[i][j].m_T[3]=(float)(-1.0*float((ReceiveCommand[26+j*48+i*192]*256+ReceiveCommand[27+j*48+i*192])/100.0));
    }
    else
    pWnd->m_important[i][j].m_T[3]=float((ReceiveCommand[26+j*48+i*192]*256+ReceiveCommand[27+j*48+i*192])/100.0);

             if(ReceiveCommand[28+j*48+i*192]&0x80)
    {
    ReceiveCommand[28+j*48+i*192]-=0x80;
    pWnd->m_important[i][j].m_T[4]=float(-1.0*float((ReceiveCommand[28+j*48+i*192]*256+ReceiveCommand[29+j*48+i*192])/100.0));
    }
    else
    pWnd->m_important[i][j].m_T[4]=float((ReceiveCommand[28+j*48+i*192]*256+ReceiveCommand[29+j*48+i*192])/100.0);

    if(ReceiveCommand[30+j*48+i*192]&0x80)
    {
    ReceiveCommand[30+j*48+i*192]-=0x80;
    pWnd->m_important[i][j].m_T[5]=(float)(-1.0*float((ReceiveCommand[30+j*48+i*192]*256+ReceiveCommand31+j*48+i*192])/100.0));
    }
    else
    pWnd->m_important[i][j].m_T[5]=float((ReceiveCommand[30+j*48+i*192]*256+ReceiveCommand[31+j*48+i*192])/100.0);

    if(ReceiveCommand[32+j*48+i*192]&0x80)
    {
    ReceiveCommand[32+j*48+i*192]-=0x80;
    pWnd->m_important[i][j].m_T[6]=float(-1.0*float((ReceiveCommand[32+j*48+i*192]*256+ReceiveCommand[33+j*48+i*192])/100.0));
    }
    else
    pWnd->m_important[i][j].m_T[6]=float((ReceiveCommand[32+j*48+i*192]*256+ReceiveCommand[33+j*48+i*192])/100.0);
            if(ReceiveCommand[34+j*48+i*192]&0x80)
    {
    ReceiveCommand[34+j*48+i*192]-=0x80;
    pWnd->m_important[i][j].m_T[7]=float(-1.0*float((ReceiveCommand[34+j*48+i*192]*256+ReceiveCommand[35+j*48+i*192])/100.0));
    }
    else
    pWnd->m_important[i][j].m_T[7]=float((ReceiveCommand[34+j*48+i*192]*256+ReceiveCommand[35+j*48+i*192])/100.0);
           if(ReceiveCommand[36+j*48+i*192]&0x80)
           {
    ReceiveCommand[36+j*48+i*192]-=0x80;
    pWnd->m_important[i][j].m_T[8]=float(-1.0*float((ReceiveCommand[36+j*48+i*192]*256+ReceiveCommand[37+j*48+i*192])/100.0));
    }
    else
    pWnd->m_important[i][j].m_T[8]=float((ReceiveCommand[36+j*48+i*192]*256+ReceiveCommand[37+j*48+i*192])/100.0);
    if(ReceiveCommand[38+j*48+i*192]&0x80)
    {
    ReceiveCommand[38+j*48+i*192]-=0x80;
    pWnd->m_important[i][j].m_T[9]=float(-1.0*float((ReceiveCommand[38+j*48+i*192]*256+ReceiveCommand[39+j*48+i*192])/100.0));
    }
    else
    pWnd->m_important[i][j].m_T[9]=float((ReceiveCommand[38+j*48+i*192]*256+ReceiveCommand[39+j*48+i*192])/100.0);

       }
       ::SendMessage(pWnd->m_hWnd,WM_NEW_DATA_COME,0,0);
       
       }
    } pWnd->closed_thread1=true;
    return 0;

    }
      

  2.   

    晕, 你把源码发给我吧. 我给你看[email protected]
      

  3.   


      用BoundsChecker检查一下看.
      

  4.   

    你的问题可能出在线程3中数据库处理部分,
    我以前用MFC ODBC,发现线程结束后,有关
    数据库的资源都没被释放掉,即使new,delete,
    open,close是在一一对应的情况下也是这样。
      

  5.   

    另外,Boundschecker并不是万能的。
      

  6.   

    不好意思,看错了,
    既然你的程序让内存不停的涨,仔细检查一下
    你的频繁调用的那些代码,例如你说的
    3秒钟就调用一次的Thread3,你用return
    还是ExitThread结束线程?
      

  7.   

    能发一个给我吗?
    程序太长了,在网上如何仔细研究呢?
    Email:
    [email protected]
      

  8.   

    可能是GDI资源没有释放。
    在brush、pen等资源使用完以后,加上:
    brush.DeleteObject();
      

  9.   

    像我说的这种情况,一般是不会被发现的,除非是在OnTimer或循环中使用。
      

  10.   

    同意 seeclear(看得清楚) 的看法
    有些gdi资源恢复或删除的不够充分、及时(虽然你有做但可能不够)
    我就碰到这种情况,使内存耗尽
      

  11.   

    也给我发一个吧,我看看。
    [email protected]
      

  12.   


      还没有搞定啊!  发一个给我看一下!
      [email protected]