-4

オペレーティング システムがメモリの割り当てを解除するのはいつですか? パフォーマンス カウンターを使用しても削除されません。以下のコードを参照してください。割り当て前のメモリ使用量と割り当て解除後のメモリ使用量の差は 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;
        }
4

1 に答える 1

1

システムは、そのメモリを使用しているプログラムが終了した後、つまり、return 0メインの後にメモリの割り当てを解除します。関数が呼び出されたときにメモリが解放されていないGetProcessMemoryInfoため、ゼロになるはずのメモリ使用量に大きな違いがあります。実際、システムは、プログラムが終了した直後にメモリの割り当てを解除しています (常にそうしています)。

ただし、明確なように感じるべきではありません。リークは2GBのメモリであり、LOTであると言いました。あなたのプログラムが実行するのにそれほど多くのメモリが必要であることは非常に疑わしいです。使用されていない変数のためにメモリを解放するために、コード内の場所を見つけることを検討する必要があります。

于 2013-07-30T13:42:30.927 に答える