[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Memory allocations when recycling a table
- From: Richter, Jörg <Joerg.Richter@...>
- Date: Wed, 12 Mar 2014 09:56:50 +0000
Hi,
[Lua 5.2.2]
While trying to reduce the memory allocations of our application I came
across a function that always allocates a table, sets some members, calls another
function with this table as argument. Both the caller and the callee don't reference
the table thereafter. I thought this would be a good candidate to always use the
same table.
But when using our custom memory allocator, I still see a lot of allocations at this
point that I dont expect anymore.
You can see the behaviour with the following program. I would expect that the loop
reaches a state, where no more memory allocations are neccesary. But like 2 times
out of 3 the following output happens:
loop
ptr=(nil) osize=0 nsize=0 res=(nil)
ptr=(nil) osize=0 nsize=80 res=0x937da40
ptr=0x937d9e8 osize=80 nsize=0 res=(nil)
loop
ptr=(nil) osize=0 nsize=0 res=(nil)
ptr=(nil) osize=0 nsize=80 res=0x937d9e8
ptr=0x937da40 osize=80 nsize=0 res=(nil)
[repeated...]
As you can see, one loop always frees the block allocated in the previous loop, and
a new block of the same size will be allocated. This seems unnecessary.
I suspect that hash-collisions are somehow responsible for this behaviour. Because it
does not happen every time.
Is this to be expected?
Jörg
#include <lua.h>
#include <stdlib.h>
#include <stdio.h>
void* realalloc( void* ptr, size_t osize, size_t nsize )
{
if( nsize == 0 )
{
free( ptr );
return NULL;
}
return realloc( ptr, nsize );
}
void* alloc( void* ud, void* ptr, size_t osize, size_t nsize )
{
void* res = realalloc( ptr, osize, nsize );
printf( "ptr=%p osize=%d nsize=%d res=%p\n", ptr, (int)osize, (int)nsize, res );
return res;
}
int main()
{
int i;
lua_State* L = lua_newstate( alloc, 0 );
lua_pushstring( L, "xyz" );
lua_pushstring( L, "valid" );
lua_pushstring( L, "value" );
lua_pushstring( L, "linepos" );
lua_pushstring( L, "linecol" );
lua_pushstring( L, "fashion" );
lua_newtable( L );
for( i = 0; i < 1000; ++i )
{
printf( "loop\n" );
lua_pushinteger( L, 4 );
lua_setfield( L, -2, "valid" );
lua_pushstring( L, "xyz" );
lua_setfield( L, -2, "value" );
lua_pushnil( L );
lua_setfield( L, -2, "linepos" );
lua_pushnil( L );
lua_setfield( L, -2, "fashion" );
lua_pushnil( L );
lua_setfield( L, -2, "linecol" );
}
}