Memory allocations when recycling a table
[
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: 2014年3月12日 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" );
 }
}