char sPageAdress[200];
char sDataBuf[400000];CInternetSession iHttpSession;
CStdioFile* g_pFile;g_pFile = NULL;iHttpSession.SetOption(INTERNET_OPTION_CONNECT_TIMEOUT,1000 * 30);while(1)
{
    ......
    try
   {
g_pFile = iHttpSession.OpenURL(sPageAdress, 0, INTERNET_FLAG_TRANSFER_BINARY |  INTERNET_FLAG_RELOAD, NULL, 0);
Sleep(1000);
g_pFile->Read(sDataBuf, 400000 - 1);
g_pFile->Read(sTemp, 100);
    }
    catch(CException* e)
    {
iHttpSession.Close();
return false;
    }
}
......运行这一段程序时,应用程序占用的内存持续上升,基本上每一次循环内存上升4K,非常有规律。
我怀疑系统在iHttpSession.OpenURL或g_pFile->Read时开辟缓存,而且最终没释放。
有没有遇到整个问题的,有什么办法可以解决啊?

解决方案 »

  1.   

    openurl 后是不是要先close?
      

  2.   

    不能Close,Close后就不能再OpenURL了
      

  3.   

    看起来没有明显的内容泄露
    代码不全,楼主又没有说明自己的代码的逻辑,估计没人可以帮你请尝试在g_pFile->Read(sTemp, 100);之后关闭g_pFile.
      

  4.   

    我同意baodi_z的说法。
    C语言没有自动回收资源。得自己手工的去做。
    你每次循环都先执行
    g_pFile = iHttpSession.OpenURL(sPageAdress, 0, INTERNET_FLAG_TRANSFER_BINARY | INTERNET_FLAG_RELOAD, NULL, 0);
    但使用完后你没有关闭g_pFile,就让它又指向一个新的内存地址。原先的文件对象就一直在内存中不能被删除。所以你的内存就会一直增大。
      

  5.   

    我做了一个测试程序,内存一样也是不停的增加
    void CTestDlg::OnOK() 
    {
    // TODO: Add extra validation here
    int i = 0; strcpy(m_page[0], "http://www.yahoo.com.cn/");
    strcpy(m_page[1], "http://www.99v.com.cn/Article/softtech/program/vc/sl/200503/19397.html");
    strcpy(m_page[2], "http://123456789.it.com.cn/");
    strcpy(m_page[3], "http://book.edu.qq.com/book/67/0028.htm");
    strcpy(m_page[4], "http://train.piao.com.cn/lianxi.asp?id=96151");
    while(i < 5)
    {
    OpenURLFunc(i);
    i ++;
    } CDialog::OnOK();
    }int CTestDlg::OpenURLFunc(int i)
    {
    char buf[400000];
    int len = 0;
    CInternetSession iHttpSession;
    CStdioFile* g_pFile; try
    {
    Sleep(2000);
    g_pFile = iHttpSession.OpenURL(m_page[i], 0, INTERNET_FLAG_TRANSFER_ASCII | INTERNET_FLAG_DONT_CACHE, NULL, 0); Sleep(2000);
    len = g_pFile->Read(&buf, 400000 - 1);
    }
    catch(CException* e)
    {
    ;
    } g_pFile->Close();
    iHttpSession.Close();
    delete [] g_pFile;
    g_pFile = NULL; return true;
    }TestDlg.h文件中定义的m_page[10][100];测试结果,每当运行
    g_pFile = iHttpSession.OpenURL(m_page[i], 0, INTERNET_FLAG_TRANSFER_ASCII | INTERNET_FLAG_DONT_CACHE, NULL, 0);
    时内存都会增加,不知道为什么,感觉我的程序没什么问题啊。
    大家如果有时间可以试一下,会不会是windows API的BUG。
      

  6.   

    len = g_pFile->Read(&buf, 400000 - 1); 应该是len = g_pFile->Read(buf, 400000 - 1);
     delete [] g_pFile; 应该是 delete g_pFile; 测试时只有第一次内存会增加很多(加载动态连接库),稳定之后不会增加
      

  7.   

    CInternetSession  的 OpenURL 函数 创建一个 以CStdiofile*为base class的文件类. 他是用new 创建的,所以你必须delete掉
    当你调用
    CStdiofile 具有缓冲区,他是自动分配的. 当调用g_pFile->Read(sDataBuf, 400000 - 1);时,分配了4K左右的缓冲区(我猜的,没有研究过CStdioFile的代码). 
    因为你没有delete掉g_pFile,所以他的缓冲区也没有释放. 
    是市 delete g_File,应该不错.你的 try结构有问题的,因为没有释放空间,建议使用__try ... __finally来完成 结合 __try ... __except__try{
    __try{...
    }
    __finally
    {
      delete g_pfile;
    }
    }
    __except(1)
    {
       iHettpSession.close();
       return false;
    }这样 出现异常也会同样释放空间.而且我觉得代码也有问题.
    是否是读一个http文件呢?正确的方式应该是
    __try
    {
      g_pfile = iHttpSession.OpenURL( ... );
      while(!g_pFile->eof())
      {
        g_pFile.Read(....);
       .....
      }
    }
    __finally{
      delete g_pFile;
      iHttpSession.close();
    }
      

  8.   

    纠正一下错误:
    len = g_pFile->Read(&buf, 400000 - 1); 确实应该是len = g_pFile->Read(buf, 400000 - 1);
    delete [] g_pFile或者delete g_pFile都可以,这没什么问题。 测试时第一次内存会增加很多(加载动态连接库),确实如此。
    稳定之后每次OpenURL时,内存增加4K。
      

  9.   

    终于找到原因了
    _AFXCOLL_INLINE void CMapPtrToPtr::SetAt(void* key, void* newValue)
    { (*this)[key] = newValue; }MFC把每个CInternetSession实例加进索引中,目的是什么暂时还没
    查到估计,是为了避免重复读取同一个网页吧。
    看来如果避免内存持续增加,只能重写OpenURL了。