【问题标题】:How to make sure memory leak is being taken care of?如何确保内存泄漏得到处理?
【发布时间】:2013-07-30 16:31:25
【问题描述】:

操作系统何时释放内存?当我使用性能计数器时,我没有看到它被删除。请参阅下面的代码。分配前的内存使用量和取消分配后的内存使用量之间的差异应该是 0 但不是。

基本上我有一个托管在 dllhost 中的 COM dll,它会泄漏内存(在 32 位 MS-OS 上超过 2GB)。

            #include "stdafx.h"
        #include <stdlib.h>
        #include <crtdbg.h>
        #include <list>
        #include <map>



        //#define _CRTDBG_MAP_ALLOC
        #include <stdlib.h>
        #include <crtdbg.h>

        using namespace std;
        /*
        #ifdef _DEBUG
           #ifndef DBG_NEW
              #define DBG_NEW new ( _NORMAL_BLOCK , __FILE__ , __LINE__ )
              #define new DBG_NEW
           #endif
        #endif  // _DEBUG
        */
        template <class K, class T, class Pr = less<K>, class A = allocator<T> > 
        class CTypedHeapPtrMap : public map<K, T, Pr, A > 
        {
        public:   
            // Construction
            CTypedHeapPtrMap()
            {
            };   

            // Destructor
            ~CTypedHeapPtrMap() 
            {
                DeleteContents();
            };  

            void DeleteContents() 
            {
                iterator ItEntry;

                /* Empty the list and delete memory */
                ItEntry = begin();   
                while (ItEntry != end())
                {

                    T pT = ItEntry->second;
                    delete[] pT;
                    pT = NULL;
                    ItEntry++;
                }
                map<K,T,Pr,A>::clear();
            };  
        };

        typedef CTypedHeapPtrMap<long, char*>                   VALIDATION_MAP;

        int _tmain(int argc, _TCHAR* argv[])
        {
            PROCESS_MEMORY_COUNTERS_EX pmcx = {};

            pmcx.cb = sizeof(pmcx);
            GetProcessMemoryInfo(GetCurrentProcess(),reinterpret_cast<PROCESS_MEMORY_COUNTERS*>(&pmcx), pmcx.cb);

            //assumuing GetProcessMemoryInfo call above allocates some memory. So get the memory status again
            pmcx.cb = sizeof(pmcx);
            GetProcessMemoryInfo(GetCurrentProcess(),reinterpret_cast<PROCESS_MEMORY_COUNTERS*>(&pmcx), pmcx.cb);
            printf(" Memory usage (Before allocation) = %ld\n", pmcx.WorkingSetSize);

            {
                VALIDATION_MAP pStr;

                char *ptr1 = new char[10000];
                pStr.insert(VALIDATION_MAP::value_type(1, ptr1));
                char *ptr2 = new char[10000];
                pStr.insert(VALIDATION_MAP::value_type(2, ptr2));
                char *ptr3 = new char[10000];
                pStr.insert(VALIDATION_MAP::value_type(3, ptr3));
                char *ptr4 = new char[10000];
                pStr.insert(VALIDATION_MAP::value_type(4, ptr4));
                char *ptr5 = new char[10000];
                pStr.insert(VALIDATION_MAP::value_type(5, ptr5));
                char *ptr6 = new char[10000];   
                pStr.insert(VALIDATION_MAP::value_type(6, ptr6));
                char *ptr7 = new char[10000];
                pStr.insert(VALIDATION_MAP::value_type(7, ptr7));
                char *ptr8 = new char[10000];
                pStr.insert(VALIDATION_MAP::value_type(8, ptr8));
                char *ptr9 = new char[10000];
                pStr.insert(VALIDATION_MAP::value_type(9, ptr9));
            }
            pmcx.cb = sizeof(pmcx);
            GetProcessMemoryInfo(GetCurrentProcess(),reinterpret_cast<PROCESS_MEMORY_COUNTERS*>(&pmcx), pmcx.cb);
            printf(" Memory usage (After de-allocation) = %ld\n", pmcx.WorkingSetSize);
            Sleep(60000);//sleep for a minute
            return 0;
        }

【问题讨论】:

  • 简单:不要造成泄漏

标签: memory-leaks


【解决方案1】:

在使用该内存的程序终止后,系统将释放该内存,即在您的 main 中的 return 0 之后。调用 GetProcessMemoryInfo 函数时内存尚未释放,因此当它应该为零时内存使用量会有很大差异。系统实际上正在释放内存(它总是如此),就在您的程序结束之后。

但是,您不应该觉得自己很清楚,您说泄漏是 2GB 内存,这是很多,我高度怀疑您的程序需要那么多内存才能运行。你真的应该考虑在你的代码中找到一些地方来为没有被使用的变量释放内存。

【讨论】:

  • VALIDATION_MAP pStr 超出范围,因此调用了析构函数。那个时候操作系统不会释放内存吗?
  • VALIDATION_MAP pStr 超出范围,因此调用了析构函数。那个时候操作系统不会释放内存吗?关于 2 GB 内存问题 - 我有一个 C++ 代码,它根据某种优化计算一些东西。优化是在递归函数中进行的。该函数在需要时在堆上分配内存。析构函数假设释放它。这个特定的 dll 托管在 dllhost 中,并且代码是多线程的。因此,如果操作系统仅在程序退出后解除分配,那么它对我没有好处。
  • 你真的不应该依赖操作系统为你释放内存,永远。 C 和 C++ 是低级的并且非常强大是有原因的,你应该自己处理分配和释放,它只保证程序退出后内存会被释放
猜你喜欢
  • 1970-01-01
  • 2012-02-12
  • 2015-06-14
  • 2012-12-11
  • 2017-08-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-01
相关资源
最近更新 更多