🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: borland.public.cppbuilder.nativeapi
Article #9217

Re: Problem with memory again

#9217
From: Andrue Cope [TeamB]
Date: Mon, 26 Jul 2004 08:23
153 lines
4826 bytes
This is what we developed. It's crude and not designed to be fast but
it helps us avoid the scenario I described. BTW I'll reiterate that I
don't know if the HM is at fault or not - it's just my theory :)

// .h
/*
  Use this class when you are likely to be reallocating lots of memory
blocks.
  This class will reduce calls to the Heap Manager by recycling old
memory blocks.

  It is not a directly performance related class. The idea is to avoid
heap
    fragmentation and thus hopefully avoid runaway memory consumption.
*/

struct TCachedItem
{
  bool          InUseF;
  TCachedItem * Next;
  void *        Data;
  DWORD         Size;

  TCachedItem()
  {
    Next=NULL;
    Data=NULL;
    InUseF=false;
  }

  ~TCachedItem()
  {
    KillAry( Data );
    KillObj( Next );
  }
};

const int MAX_CACHED_ALLOC = 1024*1024;
const int MAX_CACHED_ITEMS = 128;

class TOCachedAllocator
{
    TCachedItem MyCachedItems;
    DWORD       MyTotalSize;
    WORD        MyTotalItems;

    template<typename ObjectType> ObjectType * fixupMemoryBlock(
ObjectType * Data,
                                                                 DWORD
Size,
                                                                 bool
InitF )
    {
      if( InitF )
        memset( Data, 0, Size );

      return Data;
    }
  public:
    TOCachedAllocator();

    // Allocate/recycle new memory block.
#pragma warn -inl
    template<typename ObjectType> ObjectType * Get( ObjectType *&
Pointer,
                                                    int           Count,
                                                    bool
InitF=true )
    {
      DWORD reqSize=Count;
      reqSize*=sizeof( *Pointer );

      // First look for a free block of that size
      TCachedItem * itemPtr=MyCachedItems.Next;

      while( itemPtr&&
             ( itemPtr->InUseF||
               itemPtr->Size!=reqSize ) )
        GoNext( itemPtr );

      if( itemPtr )
      {
        itemPtr->InUseF=true;
        return Pointer=fixupMemoryBlock( reinterpret_cast<ObjectType
*>( itemPtr->Data ),
                                 reqSize,
                                 InitF );
      }

      // Consider allocating a new block
      if( ( reqSize+MyTotalSize>MAX_CACHED_ALLOC )||
          ( MyTotalItems==MAX_CACHED_ITEMS ) )
        return Pointer=fixupMemoryBlock( new ObjectType[ Count ],
                                 reqSize,
                                 InitF );

      MyTotalSize+=reqSize;
      ++MyTotalItems;

      itemPtr=new TCachedItem();
      itemPtr->InUseF=true;
      itemPtr->Size=reqSize;
      itemPtr->Data=new ObjectType[ Count ];
      itemPtr->Next=MyCachedItems.Next;
      MyCachedItems.Next=itemPtr;

      return Pointer=fixupMemoryBlock( reinterpret_cast<ObjectType *>(
itemPtr->Data ),
                               itemPtr->Size,
                               InitF );
    }

    // Deallocate/return object
    template<typename ObjectType> void Release( ObjectType *& Pointer )
    {
      // Look for this block in our list
      TCachedItem * itemPtr=MyCachedItems.Next;

      while( itemPtr&&
             ( itemPtr->Data!=Pointer ) )
        GoNext( itemPtr );

      if( !itemPtr )
      { // Not ours
        delete[] Pointer;
      }
      else
      { // Ours - mark it as unused
        itemPtr->InUseF=false;
      }
    }
#pragma warn .inl
};

extern TOCachedAllocator CachedAllocator;

#endif

// .cpp
TOCachedAllocator
  ::TOCachedAllocator()
{
  MyTotalSize=MyTotalItems=0;
}

TOCachedAllocator CachedAllocator;

It's quite old and could probably benefit from the STL. std::set for
the list of blocks would probably be a good start :)
-- 
Andrue Cope [TeamB]
[Bicester, Uk]
http://info.borland.com/newsgroups/guide.html
Technical Details
Message-ID: <4104bf98@newsgroups.borland.com>
Path: arc1-ca.pugleaf.net!g2news1.google.com!news2.google.com!proxad.net!213.200.89.82.MISMATCH!tiscali!newsfeed1.ip.tiscali.net!newsfeed00.sul.t-online.de!newsfeed01.sul.t-online.de!t-online.de!newsgroups.borland.com!not-for-mail
References: <4100b152@newsgroups.borland.com> <4100c97e@newsgroups.borland.com> <4101d3e2@newsgroups.borland.com>

Show Full Headers
Complete Article Headers
X-Google-Thread: 10cc67,e9f11b4f112d3007
X-Google-Attributes: gid10cc67,public
X-Google-Language: ENGLISH,ASCII-7-bit
From: "Andrue Cope [TeamB]" <no.spam@spammy.com>
Subject: Re: Problem with memory again
Newsgroups: borland.public.cppbuilder.nativeapi
References: <4100b152@newsgroups.borland.com> <4100c97e@newsgroups.borland.com> <4101d3e2@newsgroups.borland.com>
User-Agent: XanaNews/1.16.3.1
MIME-Version: 1.0
Content-Type: text/plain; charset=iso-8859-1
NNTP-Posting-Host: 217.207.223.34
Message-ID: <4104bf98@newsgroups.borland.com>
Date: 26 Jul 2004 01:23:52 -0700
X-Trace: newsgroups.borland.com 1090830232 217.207.223.34 (26 Jul 2004 01:23:52 -0700)
Lines: 153
X-Authenticated-User: acope
Path: arc1-ca.pugleaf.net!g2news1.google.com!news2.google.com!proxad.net!213.200.89.82.MISMATCH!tiscali!newsfeed1.ip.tiscali.net!newsfeed00.sul.t-online.de!newsfeed01.sul.t-online.de!t-online.de!newsgroups.borland.com!not-for-mail