亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費注冊 查看新帖 |

Chinaunix

  平臺 論壇 博客 文庫
123下一頁
最近訪問板塊 發(fā)新帖
查看: 9991 | 回復(fù): 20
打印 上一主題 下一主題

[C] 線程創(chuàng)建子線程,線程退出時,釋放了內(nèi)存,但是TOP中只看到有一般的內(nèi)存被釋放了 [復(fù)制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報告]
發(fā)表于 2014-02-12 14:40 |只看該作者 |倒序瀏覽

架構(gòu)是這樣的。

主進(jìn)程先初始化了一個線程池A,當(dāng)其中一個線程接收到任務(wù)的時候,就會去創(chuàng)建幾個子線程B來處理任務(wù)。(該A1線程使用pthread_jion等待子線程B退出,子線程用pthread_exit退出)。在子線程B中,使用了malloc函數(shù)連續(xù)分配了2段內(nèi)存。任務(wù)處理完后,在退出pthread_exit前,釋放他們。

其中的異,F(xiàn)象是這樣的,如果我在子線程B中加了日志打印的函數(shù),那么所有子線程退出時,上面申請的兩個連續(xù)內(nèi)存有一半的大小在top中顯示為未釋放(實際上,已經(jīng)釋放了,我向那2段內(nèi)存中memcpy程序core了)。如果我在子線程B中不加日志打印函數(shù),就不會有這個現(xiàn)象。

日志打印函數(shù),檢查過,沒有什么問題。

  1. #define LOG_INFO        Log_SysInfo(LOG_LEVEL_INFO,__FILE__,__LINE__),Log_Msg

  2. void Log_SysInfo(const int iLogLevel, const char *pszFileName, const int iNum)
  3. {
  4.     int i = 0;
  5.     char szLogTime[30];

  6.     //  加一個寫日志的線程鎖
  7.     pthread_mutex_lock(&g_WriteLog);

  8.     memset(szLogTime, 0, sizeof(szLogTime));
  9.     memset(g_szLogHead, 0, sizeof(g_szLogHead));

  10.     g_iLogLevel = iLogLevel;

  11.     //  如果設(shè)置的日志級別小直接返回
  12.     if(g_iSetLogLevel < g_iLogLevel)
  13.     {
  14.         return;
  15.     }

  16.     Log_Check();

  17.     timev_GetLogTime(szLogTime);
  18.     snprintf(g_szLogHead, sizeof(g_szLogHead), "%s %s L=%d T=%ld E=%d ", szLogTime, pszFileName,
  19.                  iNum, pthread_self(), errno);

  20.     switch(iLogLevel)
  21.     {
  22.         case LOG_LEVEL_ERROR:
  23.              sprintf(g_szLogHead + strlen(g_szLogHead), "%s", "[ERROR] ");
  24.              break;
  25.         case LOG_LEVEL_WARN:
  26.              sprintf(g_szLogHead + strlen(g_szLogHead), "%s", "[WARN] ");
  27.              break;
  28.         case LOG_LEVEL_DEBUG:
  29.              sprintf(g_szLogHead + strlen(g_szLogHead), "%s", "[DEBUG] ");
  30.              break;
  31.         case LOG_LEVEL_INFO:
  32.              sprintf(g_szLogHead + strlen(g_szLogHead), "%s", "[INFO] ");
  33.              break;
  34.         case LOG_LEVEL_ALL:
  35.              sprintf(g_szLogHead + strlen(g_szLogHead), "%s", "[ALL] ");
  36.              break;
  37.         default:
  38.              break;
  39.     }
  40. }

  41. void Log_Msg(const char *format, ...)
  42. {
  43.     FILE *fp;
  44.     va_list args;
  45.     int  olderrno;
  46.     //char szContext[1024*10];    //  分配10K的臨時變量空間,如果用內(nèi)存分配會不會影響性能
  47.     int i;

  48.     //  如果設(shè)置的日志級別小,則直接返回
  49.     if(g_iSetLogLevel < g_iLogLevel)
  50.     {
  51.         pthread_mutex_unlock(&g_WriteLog);
  52.         return;
  53.     }
  54.     olderrno = errno;     
  55.     //memset(szContext, 0, sizeof(szContext));

  56.     if(NULL != (fp = fopen(g_szLogFile, "a+")))
  57.     {
  58.         fprintf(fp, "%s", g_szLogHead);
  59.         va_start(args, format);
  60. //        fprintf(fp, "%s\n", szContext);
  61.         vfprintf(fp, format, args);
  62. //        fflush(fp);
  63.         va_end(args);
  64.         fprintf(fp, "%s", "\n");
  65.         fclose(fp);
  66.     }
  67.     else
  68.     {
  69.         printf("fopen error, errno=%d, file=%s\n", errno, g_szLogFile);
  70.         perror("fopen");
  71.         //printf("context1 [%s], file[%s:%d] \n", szContext, __FILE__, __LINE__);
  72.     }
  73.     errno = olderrno;

  74.     pthread_mutex_unlock(&g_WriteLog);
  75. }
復(fù)制代碼

論壇徽章:
0
2 [報告]
發(fā)表于 2014-02-12 14:45 |只看該作者
這個是子線程的代碼,就算是這樣,先連續(xù)申請兩段內(nèi)存,然后釋放,top中顯示就沒有釋放完。  如果我在pReadMemory申請后,再釋放,pWriteMemory申請后,再釋放就是正常的。搞不懂是什么意思,求大哥大姐幫幫忙!
  1. void *trans_SingleThread(void *pData)
  2. {
  3.     int iRet;
  4.     MultTransData *pMultTransData = (MultTransData *)pData;
  5.     MMapData *pMMapData = NULL;
  6.     ListNode *pTemp = NULL;
  7.     void *pReadMemory = NULL;
  8.     void *pWriteMemory = NULL;
  9.     MMapData *pFirstSection = NULL;

  10.     pTemp = pMultTransData->m_pMMapDataList;
  11.     pFirstSection = (MMapData *)pTemp->pData;


  12.     //  為寫空間分配內(nèi)存地址
  13.     pWriteMemory = ufs_MallocMemory(pFirstSection->m_lWriteTotalSize);
  14.     if(NULL == pWriteMemory)
  15.     {
  16.         LOG_ERROR("Malloc Memory Failure!");
  17.         ufs_vFreeNormalMemory(&pReadMemory);
  18.         iRet = RT_FAILURE;
  19.         pthread_exit((void *)&iRet);
  20.     }

  21.     //  為讀空間分配內(nèi)存地址
  22.     pReadMemory = ufs_MallocMemory(pFirstSection->m_lReadTotalSize);
  23.     if(NULL == pReadMemory)
  24.     {
  25.         LOG_ERROR("Malloc Memory Failure!");
  26.         iRet = RT_FAILURE;
  27.         pthread_exit((void *)&iRet);
  28.     }


  29. LOG_DEBUG("Thread Will Quit");

  30. ufs_vFreeNormalMemory(&pReadMemory);
  31. ufs_vFreeNormalMemory(&pWriteMemory);



  32. pthread_exit((void *)&iRet);

  33. }
復(fù)制代碼

論壇徽章:
0
3 [報告]
發(fā)表于 2014-02-12 16:11 |只看該作者
求幫助!有沒有哪個可以幫忙看看呢

論壇徽章:
3
射手座
日期:2014-08-18 12:15:53戌狗
日期:2014-08-22 09:53:36寅虎
日期:2014-08-22 14:15:29
4 [報告]
發(fā)表于 2014-02-12 16:43 |只看該作者
本帖最后由 gaojl0728 于 2014-02-12 16:45 編輯

回復(fù) 3# korpus


    1. 能不能把LOG_DEBUG的代碼貼出來。
2. 你是看top的哪一個字段?
3. 你說“我向那2段內(nèi)存中memcpy程序core了”, 什么叫core了, 是crash了嗎?
4. crash了, 不一定能證明就是釋放了, 把memcpy的代碼貼出來

論壇徽章:
0
5 [報告]
發(fā)表于 2014-02-12 16:56 |只看該作者
回復(fù) 4# gaojl0728


    你好,謝謝你的關(guān)注,
1 LOG_DEBUG,貼出來了 ,就在第一個代碼里面的
2 top的res字段
3 意思好像沒有表達(dá)清楚,意思是,在我free那2段內(nèi)存后,為了檢查是否真的釋放了,然后向釋放的內(nèi)存memcpy內(nèi)容,然后程序crash了
4 memcpy(pReadMemory, "12345", 5);

論壇徽章:
3
射手座
日期:2014-08-18 12:15:53戌狗
日期:2014-08-22 09:53:36寅虎
日期:2014-08-22 14:15:29
6 [報告]
發(fā)表于 2014-02-12 17:10 |只看該作者
1. 你第一行貼的是LOG_INFO, 我想看看LOG_DEBUG。
2. ufs_vFreeNormalMemory傳遞的為什么是雙重指針,難道會把參數(shù)設(shè)置為NULL?
如果是寫NULL的話,你就不需要memcpy測試了, 直接看看是不是NULL就行了
3. 能不能把ufs_MallocMemory和ufs_vFreeNormalMemory的代碼貼出來看看?
如果實現(xiàn)是用的malloc和free, 那內(nèi)存可能被glibc的內(nèi)存池回收了,并沒有還給內(nèi)核。把代碼貼出來看看吧
4. pFirstSection->m_lWriteTotalSize和pFirstSection->m_lReadTotalSize的大小多少?

論壇徽章:
3
射手座
日期:2014-08-18 12:15:53戌狗
日期:2014-08-22 09:53:36寅虎
日期:2014-08-22 14:15:29
7 [報告]
發(fā)表于 2014-02-12 17:11 |只看該作者
回復(fù) 5# korpus


    1. 你第一行貼的是LOG_INFO, 我想看看LOG_DEBUG。
2. ufs_vFreeNormalMemory傳遞的為什么是雙重指針,難道會把參數(shù)設(shè)置為NULL?
如果是寫NULL的話,你就不需要memcpy測試了, 直接看看是不是NULL就行了
3. 能不能把ufs_MallocMemory和ufs_vFreeNormalMemory的代碼貼出來看看?
如果實現(xiàn)是用的malloc和free, 那內(nèi)存可能被glibc的內(nèi)存池回收了,并沒有還給內(nèi)核。把代碼貼出來看看吧
4. pFirstSection->m_lWriteTotalSize和pFirstSection->m_lReadTotalSize的大小多少?

論壇徽章:
0
8 [報告]
發(fā)表于 2014-02-12 17:37 |只看該作者
回復(fù) 7# gaojl0728


    你好,首先謝謝您哈。
1. 你第一行貼的是LOG_INFO, 我想看看LOG_DEBUG。
  1. #define LOG_ERROR        Log_SysInfo(LOG_LEVEL_ERROR,__FILE__,__LINE__),Log_Msg
  2. #define LOG_WARN        Log_SysInfo(LOG_LEVEL_WARN,__FILE__,__LINE__),Log_Msg
  3. #define LOG_INFO        Log_SysInfo(LOG_LEVEL_INFO,__FILE__,__LINE__),Log_Msg
  4. #define LOG_DEBUG        Log_SysInfo(LOG_LEVEL_DEBUG,__FILE__,__LINE__),Log_Msg
復(fù)制代碼
2. ufs_vFreeNormalMemory傳遞的為什么是雙重指針,難道會把參數(shù)設(shè)置為NULL?
如果是寫NULL的話,你就不需要memcpy測試了, 直接看看是不是NULL就行了


是的,就是為了將其置為空,打印過,釋放后,確實也是NULL

3.函數(shù)如下
  1. void *ufs_MallocMemory(const long lSize)
  2. {
  3.     void *pAddr = NULL;
  4.     if(lSize <= 0)
  5.     {
  6.         LOG_ERROR("malloc memory size less than zero");
  7.         return NULL;
  8.     }

  9.     pAddr = malloc(lSize);
  10.     if(NULL == pAddr)
  11.     {
  12.         LOG_ERROR("malloc memory size error!, malloc size(%d)", lSize);
  13.         return NULL;
  14.     }

  15.     memset(pAddr, 0, lSize);

  16.     return pAddr;
  17. }

  18. void ufs_vFreeNormalMemory(void **pAddr)
  19. {
  20. //    LOG_WARN("TEST MEMORY FREE[%p]", *pAddr);

  21.     if(NULL == *pAddr)
  22.         return;
  23.     else
  24.         free(*pAddr);
  25.     *pAddr = NULL;
  26. }
復(fù)制代碼
是用的malloc與free,在網(wǎng)上也查了說有可能被glibc回收,但是每次我運行一次的時候,內(nèi)存就增加了。

4. pFirstSection->m_lWriteTotalSize和pFirstSection->m_lReadTotalSize的大小多少?
這幾個值是設(shè)定的值,一般在10M以上

再次謝謝哈

論壇徽章:
59
2015年亞洲杯之約旦
日期:2015-01-27 21:27:392015年亞洲杯之日本
日期:2015-02-06 22:09:41拜羊年徽章
日期:2015-03-03 16:15:432015年辭舊歲徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:50:282015元宵節(jié)徽章
日期:2015-03-06 15:50:392015年亞洲杯之阿聯(lián)酋
日期:2015-03-19 17:39:302015年亞洲杯之中國
日期:2015-03-23 18:52:23巳蛇
日期:2014-12-14 22:44:03雙子座
日期:2014-12-10 21:39:16處女座
日期:2014-12-02 08:03:17天蝎座
日期:2014-07-21 19:08:47
9 [報告]
發(fā)表于 2014-02-12 17:59 |只看該作者
內(nèi)存的問題我不猜~~



>>但是每次我運行一次的時候,內(nèi)存就增加了。

如果是指進(jìn)程已經(jīng)結(jié)束重跑的話。
就不用擔(dān)心內(nèi)存問題了。
進(jìn)程一結(jié)束,
滲漏的內(nèi)存也會被OS自動回收。

論壇徽章:
3
射手座
日期:2014-08-18 12:15:53戌狗
日期:2014-08-22 09:53:36寅虎
日期:2014-08-22 14:15:29
10 [報告]
發(fā)表于 2014-02-12 18:17 |只看該作者
本帖最后由 gaojl0728 于 2014-02-12 18:22 編輯

回復(fù) 8# korpus

glibc只是一個可疑的點,但是不確定是不是真的被內(nèi)存池回收而沒換給內(nèi)核了。
看你的代碼沒什么問題, 沒有內(nèi)存泄露, 也沒看到死鎖
如果不是被內(nèi)存池緩存的話,我感覺可能只是一個top的顯示問題
您需要登錄后才可以回帖 登錄 | 注冊

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報專區(qū)
中國互聯(lián)網(wǎng)協(xié)會會員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP