Xojo Developer Conference
25/27th April 2018 in Denver.
MBS Xojo Conference
6/7th September 2018 in Munich, Germany.

Re: allocation conflict, huge memory leaking! (Real Studio Plugins Mailinglist archive)

Back to the thread list
Previous thread: Re: allocation conflict, OSalloclen anyone?
Next thread: Can ByRef parameter be default nil ?


macosx and unix paths   -   GOLD
  Re: allocation conflict, huge memory leaking!   -   Thomas Tempelmann
   Re: allocation conflict, huge memory leaking!   -   Jonathan Johnson
    Re: allocation conflict, huge memory leaking!   -   Alfred Van Hoek
     Re: allocation conflict, huge memory leaking!   -   Alfred Van Hoek

Re: allocation conflict, huge memory leaking!
Date: 12.06.04 23:30 (Sun, 13 Jun 2004 00:30:10 +0200)
From: Thomas Tempelmann
Christian Schmitz wrote:

>> Can someone tell me how I could solve this? I learned that at least on OS
>> X, RB 5 is using malloc directly, not managing its own pool any more. But
>> what about Windows and OS 9?
>
>You could write a memory allocator for MSL which uses Memoryblocks or
>Strings from RB to do it's work.

No, I believe I can't:

If I'd get a "new" call, I'd have to return the address of the available
memory area. I.e, I'd alloc the memory using REALNewMemoryBlock. Then I'd
return from new() the result from REALMemoryBlockGetPtr. So far, so good.

But the deallocation is the problem: When I get the "delete" call, I'll
get the address of the memblk's memory area, not its object reference.
But without the obj ref I cannot dispose of the MemoryBlock again.

So, this is not a solution, I'm afraid. I'll need something more
low-level.

BTW, this is not some easy-to-ignore problem: Each time I reload the data
in my 9MB app, I'll lose about 7MB of memory! So, reloading a few times
quickly uses up available memory badly (and leads to unexpected and
unsafe quits under OS 9! - very bad!)

BTW, I've checked for leaks using DebugDumpObjects - there's no increase
in objects, meaning that I apparently dealloc them all properly. And the
amount of memory my "map" classes do use is only in the range of a few
100 KB. so, it appears to be the fragmentation that's causing the
leakage, and that'd quite a design flaw in the plugin API.

Thomas

Re: allocation conflict, huge memory leaking!
Date: 13.06.04 00:31 (Sat, 12 Jun 2004 18:31:29 -0500)
From: Jonathan Johnson

On Jun 12, 2004, at 5:30 PM, Thomas Tempelmann wrote:

> Christian Schmitz wrote:
>
>>> Can someone tell me how I could solve this? I learned that at least
>>> on OS
>>> X, RB 5 is using malloc directly, not managing its own pool any
>>> more. But
>>> what about Windows and OS 9?
>>
>> You could write a memory allocator for MSL which uses Memoryblocks or
>> Strings from RB to do it's work.
>
> No, I believe I can't:
>
> If I'd get a "new" call, I'd have to return the address of the
> available
> memory area. I.e, I'd alloc the memory using REALNewMemoryBlock. Then
> I'd
> return from new() the result from REALMemoryBlockGetPtr. So far, so
> good.
>
> But the deallocation is the problem: When I get the "delete" call, I'll
> get the address of the memblk's memory area, not its object reference.
> But without the obj ref I cannot dispose of the MemoryBlock again.
>
> So, this is not a solution, I'm afraid. I'll need something more
> low-level.

Well, you could allocate 4 bytes more than you need, set the first 4
bytes to the object reference, and then return the pointer you
allocated + 4. Then when it comes back in, you can get the four bytes
before it, and REALUnlockObject on it.

Ugly: yes. However, it'd work if you really want to accomplish such a
thing.

-Jon

(Leaving off signature due to suggesting something that I would almost
call Evil™)
_______________________________________________
Unsubscribe or switch delivery mode:
<http://support.realsoftware.com/listmanager/>

Search the archives of this list here:
<http://support.realsoftware.com/listarchives/lists.html>

Re: allocation conflict, huge memory leaking!
Date: 13.06.04 00:50 (Sat, 12 Jun 2004 19:50:40 -0400)
From: Alfred Van Hoek
on 6/12/04 7:31 PM, Jonathan Johnson at <email address removed> wrote:

>
> On Jun 12, 2004, at 5:30 PM, Thomas Tempelmann wrote:
>
>> Christian Schmitz wrote:
>>
>>>> Can someone tell me how I could solve this? I learned that at least
>>>> on OS
>>>> X, RB 5 is using malloc directly, not managing its own pool any
>>>> more. But
>>>> what about Windows and OS 9?
>>>
>>> You could write a memory allocator for MSL which uses Memoryblocks or
>>> Strings from RB to do it's work.
>>
>> No, I believe I can't:
>>
>> If I'd get a "new" call, I'd have to return the address of the
>> available
>> memory area. I.e, I'd alloc the memory using REALNewMemoryBlock. Then
>> I'd
>> return from new() the result from REALMemoryBlockGetPtr. So far, so
>> good.
>>
>> But the deallocation is the problem: When I get the "delete" call, I'll
>> get the address of the memblk's memory area, not its object reference.
>> But without the obj ref I cannot dispose of the MemoryBlock again.
>>
>> So, this is not a solution, I'm afraid. I'll need something more
>> low-level.
>
> Well, you could allocate 4 bytes more than you need, set the first 4
> bytes to the object reference, and then return the pointer you
> allocated + 4. Then when it comes back in, you can get the four bytes
> before it, and REALUnlockObject on it.
>
> Ugly: yes. However, it'd work if you really want to accomplish such a
> thing.
>
> -Jon
>
> (Leaving off signature due to suggesting something that I would almost
> call Evil)

or:

you do the following:

typedef struct MemoryData {
REALmemoryBlock mBlock;
MemoryData* next;
MemoryData* prev;
} MemoryData;

static MemoryData* gMemoryDataFirst = NULL;
static MemoryData* gMemoryDataLast = NULL;

static MemoryData* Memory_SearchMemoryBlock(void* ptr)
{
MemoryData* mdata = gMemoryDataFirst;

if (mdata != nil) {

do {
if ( ptr == REALMemoryBlockGetPtr(mdata->mBlock) ) {
return mdata;
}

mdata = mdata->next;
} while (mdata != nil);
}
return NULL;
}

static void Memory_New(REALmemoryBlock mb)
{
MemoryData* mdata = new MemoryData;

REALLockObject((REALobject)mb);
mdata->mBlock = mb;

if (gMemoryDataFirst == nil) {
gMemoryDataFirst = gMemoryDataLast = mdata;
} else {
mdata->next = gMemoryDataFirst;
gMemoryDataFirst->prev = mdata;
gMemoryDataFirst = mdata;
}
}

static void Memory_Delete(MemoryData* mdata)
{
REALUnlockObject((REALobject)mdata->mBlock);
if (mdata->next != nil)
(*(mdata->next)).prev = mdata->prev;
else gMemoryDataLast = mdata->prev;
if (mdata->prev != nil)
(*(mdata->prev)).next = mdata->next;
else gMemoryDataFirst = mdata->next;

delete mdata;
mdata = NULL;
}

This works perfectly...

Alfred

_______________________________________________
Unsubscribe or switch delivery mode:
<http://support.realsoftware.com/listmanager/>

Search the archives of this list here:
<http://support.realsoftware.com/listarchives/lists.html>

Re: allocation conflict, huge memory leaking!
Date: 13.06.04 01:38 (Sat, 12 Jun 2004 20:38:55 -0400)
From: Alfred Van Hoek
on 6/12/04 7:50 PM, Alfred Van Hoek at <email address removed> wrote:

> typedef struct MemoryData {
> REALmemoryBlock mBlock;
> MemoryData* next;
> MemoryData* prev;
> } MemoryData;
>
> static MemoryData* gMemoryDataFirst = NULL;
> static MemoryData* gMemoryDataLast = NULL;
>
> static MemoryData* Memory_SearchMemoryBlock(void* ptr)
> {
> MemoryData* mdata = gMemoryDataFirst;
>
> if (mdata != nil) {
>
> do {
> if ( ptr =BEALMemoryBlockGetPtr(mdata->mBlock) ) {
> return mdata;
> }
>
> mdata = mdata->next;
> } while (mdata != nil);
> }
> return NULL;
> }
>
> static void Memory_New(REALmemoryBlock mb)
> {
> MemoryData* mdata = new MemoryData;
>
> REALLockObject((REALobject)mb);
> mdata->mBlock = mb;
>
> if (gMemoryDataFirst = il) {
> gMemoryDataFirst = gMemoryDataLast = mdata;
> } else {
> mdata->next = gMemoryDataFirst;
> gMemoryDataFirst->prev = mdata;
> gMemoryDataFirst = mdata;
> }
> }
>
> static void Memory_Delete(MemoryData* mdata)
> {
> REALUnlockObject((REALobject)mdata->mBlock);
> if (mdata->next != nil)
> (*(mdata->next)).prev = mdata->prev;
> else gMemoryDataLast = mdata->prev;
> if (mdata->prev != nil)
> (*(mdata->prev)).next = mdata->next;
> else gMemoryDataFirst = mdata->next;
>
> delete mdata;
> mdata = NULL;
> }

For completeness here are additional calls that should cover you:

void* _MemAlloc(uint32 size)
{
REALmemoryBlock mb = NULL;

mb = REALNewMemoryBlock(size);
Memory_New(mb);
return REALMemoryBlockGetPtr(mb);
}

void _NPN_MemFree(void* ptr)
{
MemoryData* mdata = Memory_SearchMemoryBlock(ptr);
if (mdata) {
Memory_Delete(mdata);
}
}

unsigned long _MemFlush(unsigned long)
{
unsigned long flushed = Memory_DestroyAll();
return flushed;
}

unsigned long Memory_DestroyAll(void)
{
unsigned long totalsize = 0;

MemoryData* mdata = gMemoryDataFirst;

if (mdata != nil) {

do {
totalsize += REALMemoryBlockGetSize(mdata->mBlock);
Memory_Delete(mdata);
mdata = mdata->next;
} while (mdata != nil);
}
return totalsize;
}

Alfred

_______________________________________________
Unsubscribe or switch delivery mode:
<http://support.realsoftware.com/listmanager/>

Search the archives of this list here:
<http://support.realsoftware.com/listarchives/lists.html>